PhantomJS でWebサイトの画面キャプチャをとる

PHP で単にスクレイピングをするだけなら、file_get_contents して解析したり、 curl を使ったり、Simple HTML DOM Parser(http://simplehtmldom.sourceforge.net/) を使ったり、 DOMDocument を使ったり、様々が方法があります。

しかしサイトの画像キャプチャを取得するとなると、PHP のみでは一筋縄ではいきません。
今回は PhantomJS を利用する際のメモになります。

PhantomJS とは:

PhantomJS is a headless WebKit scriptable with a JavaScript API. It has fast and native support for various web standards: DOM handling, CSS selector, JSON, Canvas, and SVG.
http://phantomjs.org/

ということで、ひらたくいえば JavaScript で動かすヘッドレスブラウザということになります。


まずはこちら http://phantomjs.org/download.html から必要なものをダウンロードします。 その時点での最新版(Windows であれば phantomjs-2.1.1-windows.zip)をダウンロードします。

圧縮ファイルを解凍すると、bin/phantomjs.exe という実行ファイルがあり、これが本体になります。 これを任意のフォルダに配置します。

使い方は簡単です。JavaScript コードを書いたファイルを引数に指定して、起動します。

phantomjs.exe hello.js

公式の Hello World はこうです。

hello.js

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

phantom というオブジェクトがいて、exit() を呼ぶことで処理を終了するようです。 これを呼ばないと終了しないので注意しましょう。
APIのドキュメントも準備されていますので、必要に応じて参照します。 API | PhantomJS


本題です。
画面キャプチャを取ってみます。コードはずばり以下の通りです。

var page = require('webpage').create();

page.open('https://news.yahoo.co.jp/', function(status) {
  page.render('cap.png');
  phantom.exit();
});

open メソッドに指定したURLにアクセスし、ページがロードされると指定したコールバックが呼び出されます。
ここではチェックしていませんが status には 'success' か 'fail' が入ってくるので、それを見てエラー処理を行うことができます。

さらに render メソッドで出力先の画像ファイルパスを指定すると、そのファイルに画面キャプチャが出力されます。

キャプチャする範囲を指定する場合は clipRect を使用します。

page.clipRect = { top:0, left:0, width:760, height:400 };
page.render('cap.png');

また、デフォルトのユーザエージェント文字列だと意図しないレンダリングになる可能性がありますが、 その場合は任意のユーザエージェント文字列を指定することができます。

// 当たり前ですが open の前に設定します
page.settings.userAgent = ...任意のユーザエージェント文字列...;
page.open('https://news.yahoo.co.jp/', function(status) {



PHP から使う場合には PhantomJS のライブラリもありますが、 単に exec で phantomjs の実行ファイルを起動することでも利用できます。

exec("phantomjs.exe {$filePath}", $output, $resultCode);