karasuyamatenguの日記

 | 

2011-01-26

PhantomJS: 「最小限なheadlessのWebKitベースのJavaScriptツール」

03:24

こりゃ面白い。http://code.google.com/p/phantomjs/

"PhantomJS is a minimalistic, headless, WebKit-based, JavaScript-driven tool"

headless=スクリーンがない=コマンドと考えればいい。要はブラウザから画面と取り除いてJavaScriptによるスクリプティングを可能にしたコマンドツール。逆に言うとDOM+JavaScript+Networkingをコマンドにしたもの。

説明してもピンとこないだろうから実例を紹介する。http://code.google.com/p/phantomjs/wiki/QuickStart

hello world

hello.js

console.log('Hello, world!');
phantom.exit();

$ phantomjs hello.js

ブラウザにはないsynchronous sleep機能

phantom.sleep(1000)で簡単に寝れる。ただしブロッキングなのでその間、他のオペレーションは停止する。当然、通常のwindow.setTimeoutもできる。

コマンドラインインターフェス

argvはphantom.argsとしてアクセス可能。

if (phantom.args.length === 0) {
    console.log('Try to pass some args when invoking this script!');
} else {
    phantom.args.forEach(function (arg, i) {
            console.log(i + ': ' + arg);
    });
}
phantom.exit();

伝統的なCコマンドのようにargで始まりexit()で終るjavascriptが書けるってのは違和感のある楽しさだ。

ページをロードしてスクリプトを走らせる (Loading)

$ phantomjs hoge.js <URL>

とするとhoge.jsというスクリプトURLからロードされたページに対して実行できる。ページを読み込む時間を測るスクリプトを例にしている。

$ phantomjs loadspeed.js http://www.google.com
Loading http://www.google.com
Page title is Google
Loading time 719 msec

URLを画像化する (Rendering)

$ phantomjs rasterize.js http://ariya.github.com/svg/tiger.svg tiger.png

ネットワーク上のSVGpngに変換。

DOM操作 (DOM Manipulation)

WebKitを使っているので、DOM操作やCSSもできる。ページを読み込んで、エレメントから値を抽出することが簡単にできる。

console.log(document.getElementById('myagent').innerText);

これで読み込んだページの#myagentエレメントのテキストが出力できる。

Googleからニューヨークピザ屋の住所と電話番号を抽出する例がある。10行ちょっとこのコードだ。

if (phantom.state.length === 0) {
    phantom.state = 'pizza';
    phantom.open('http://www.google.com/m/local?site=local&q=pizza+in+new+york’);
} else {
    var list = document.querySelectorAll('div.bf');
    for (var i in list) {
        console.log(list[i].innerText);
    }
    phantom.exit();
}

googleはあの手この手でスクレーピングをさせない工夫をしてきた。しかし、このようなツールができると、ブラウザとスクレーピングプログラムとの境界がぼける。ブラウザと同じコードを使っているの区別のつけようもないだろう。いたちごっこはやめてYahooのBOSSのようにAPIを公開すればいいのに。どっちにしろこれでgoogleがスクレープしやすくなった。前から考えている「グーグルアドセンスを掲載しているコンテントファームに甘いのではないか」という仮定を検証するのにちょうどいい。

話がそれた。

インストール

make installは何もしない。必要なのはbin/phantomjsだけなのでsudo cp bin/phantomjs /usr/local/bin/でいいだろう。

参照

 |