casperjs で iTunesConnect からアプリのダウンロード数をスクレイピングしてみた

以前、 Sales and Trends からダウンロード数を出力というタイトルで iTunesConnect からアプリのダウンロード数を取得する方法について書きました。Apple 謹製のスクリプトを使っているのですが、フィルタリングが弱く柔軟に好きな情報を取得できない。何か別の方法ないか考えていたとき、casperjs でもしかしたらできるんじゃないかと思いやってみた。casperjs は主に Web のテストとかで使われるケースが多いけど、Web の情報を簡単にスクレイプできるのでかなり便利です。

casperjs とは

casperjs は Javascript で実装された PhantomJS のラッパーです。PhanomJS とはコンソール上から webkit ブラウザを操作する仕組みでクライアントサイドのテストフレームワークとして利用されています。webkit ブラウザなので chrome とか firefox とかですね。コンソール上から javascript を実行したり Cookie 書き換えたり UgerArgent 書き換えたりと色々できる。casperjs はそのラッパーなので PhantomJS にプラスして、テストやスクレイピングするための便利な機能が多く含まれています。そしてなにしろ可読性も高く、ここをクリックしたらこうなって次ここをクリックしたらこの情報を取得してという流れが分かりやすく書くことができる便利なやつです。

スクレイピング

実際にスクレイピングしてみます。コードはこんな感じです。

var user = 0;
var units = [];
var casper = require('casper').create();

casper.start('https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/', function() {
this.echo(this.getTitle());
});

casper.then(function() {
this.evaluate(function(username, password) {
document.querySelector('#accountname').value = username;
document.querySelector('#accountpassword').value = password;
document.querySelector('.sign-in').click();
}, 'ID', 'PW');
});

casper.thenOpen('https://reportingitc2.apple.com/', function() {
this.clickLabel('対象アプリ名', 'span');
});

casper.then(function() {
this.wait(3000, function() {
this.clickLabel('Lifetime', 'a');
this.wait(3000, function() {
var elements = this.getElementsInfo('#exportContainer table tbody tr td');
var j = 0;
for (i in elements) {
if (i > 1) {
units[j] = elements[i]['text'];
j++;
}
}
});
});
});

casper.then(function() {
for (i in units) {
user += Number(units[i]);
}
user = user.toString().replace(/(d)(?=(ddd)+$)/g , '$1,');
require('fs').write('units.txt', user)
});

casper.run(); 

これを実行すればアプリのダウンロード数を取得することができます。ただ要素の指定や一部の処理は公開しているアプリの数などでかわってくるかもしれないです。

先に言いましたが、casperjs は可読性が高いのでだいたい何してるか想像つくと思いますが、簡単に処理を追ってみます。

1. casper.start で URL とコールバック関数を定義しています。URL は iTunes Connect のログインページ、コールバックでは getTitleメソッドでページのタイトルを取得しコンソールに表示させています。 

2. ログイン画面に遷移させた後、casper.then の evaluate でログインフォームに ID と PW を入力します。evaluate は DOM 要素に値を挿入させたいときなどに利用します。ここでは DOM のid要素を指定してID、PWを挿入しています。

3. ここまでで iTunes Connect へのログインが完了しましたので、Sales and Trends にアクセスし対象のサービスの情報を表示させるよう処理させます。thenOpen で Sales and Trendsを開き、clickLabel  が第一引数に指定した文字列をページ上から探し、データを取得したいアプリの情報に絞っています。

4. ここから実際にデータを取得する処理になります。まず Lifetime のリンクをクリック、対象アプリの全ダウンロード状況を表示させます。wait で3秒間を置いているのは画面の読み込みが走るので念のためという感じです。読み込み完了後、getElementInfo でダウンロード数を取得し配列にいれます。配列なのは Lifetime クリックした際に年ごとにダウンロード数が表示されるので、それぞれの年のデータを配列にいれています。

5. これでデータが取得できました。最後に配列の中身の合計を出し、3桁区切りにしてファイルに出力させてます。

このスクリプトを定期実行させれば自動でデータが取得できるし、Web 上に表示させておけば誰もが数値を見る事ができますね。チームで開発していて、目標値を掲げている場合にはこのような見える化はモチベーションの一つにもなるのではと思います。拡張していけば色んなパターンのデータを自動で集計できそうです。

デメリット

このやり方は DOM 要素の構成に依存するため、iTunes Connest の UI 変更などがあるとスクリプトも変更しなければなりません。ただ指定要素などが変わってくるくらいなのでさほど面倒ではないかなと思っています。頻繁に UI 変更があるわけでもないですし。

 

以上、casperjs でアプリのダウンロード数をスクレイピングする方法についての紹介でした。

ちなみにcasperjs は Web の結合テストをおこなえる便利機能が揃っています。selenium と違い導入コストも低いですし、Web の結合テストを簡単に実行できるので、取りかかりにはおすすめです。