PhantomJS を使うとコマンドラインからウェブページのスクリーンショット(キャプチャ)を撮ることができる。

Linux, Mac OS X, Windows 上で動作可能らしいので、今回は Mac OS X で試してみた。

環境:
- Mac OS X 10.6.8 Snow Leopard
- PhantomJS 1.2.0 (development)

BuildInstructions - phantomjs - Build Instructions - headless WebKit with JavaScript API - Google Project Hosting を参考にしてインストールする。

まず、 Download Qt for Open Source C++ development on Mac OS X — Qt - A cross-platform application and UI framework から「Cocoa: Mac binary package for Mac OS X 10.5 - 10.6 (32-bit and 64-bit)」 http://get.qt.nokia.com/qt/source/qt-mac-opensource-4.7.4.dmg をダウンロードして実行して Qt をインストール。

次に PhantomJS のソースコードを github からダウンロードしてビルド。


$ git clone git://github.com/ariya/phantomjs.git && cd phantomjs && git checkout 1.2
 
$ qmake -spec macx-g++ && make

ドキュメントによると

For convenience, copy the executable bin/phantomjs.app/Contents/MacOS/phantomjs to some directory in your PATH.

とあるので、とりあえず phantomjs ファイルを適当なところにコピーして実行してみる。


$ cp ./bin/phantomjs.app/Contents/MacOS/phantomjs ../../../
 
$ cd ../../../
 
$ ./phantomjs  --version
1.2.0 (development)
 
$ ./phantomjs
 
Usage: phantomjs [options] script.[js|coffee] [script argument [script argument ...]]
 
Options:
    --load-images=[yes|no]             Load all inlined images (default is 'yes').
    --load-plugins=[yes|no]            Load all plugins (i.e. 'Flash', 'Silverlight', ...) (default is 'no').
    --proxy=address:port               Set the network proxy.
    --disk-cache=[yes|no]              Enable disk cache (at desktop services cache storage location, default is 'no').
    --ignore-ssl-errors=[yes|no]       Ignore SSL errors (i.e. expired or self-signed certificate errors).

Webページのスクリーンショットを撮る機能を持つ JavaScript のコード (rasterize.js) を書く。


$ cat ./rasterize.js 
 
var page = new WebPage(),
  address, output, size;
 
if (phantom.args.length < 2 || phantom.args.length > 3) {
  console.log('Usage: rasterize.js URL filename');
  phantom.exit();
} else {
  address = phantom.args[0];
  output = phantom.args[1];
  page.viewportSize = { width: 1024, height: 768 };
  page.open(address, function (status) {
    if (status !== 'success') {
      console.log('Unable to load the address!');
    } else {
      window.setTimeout(function () {
        page.render(output);
        phantom.exit();
      }, 1000);
    }
  });
}

PhantomJS + rasterize.js を実行してスクリーンショット画像を生成する。


$ ./phantomjs rasterize.js http://www.nilab.info/ 20110920_phantomjs_nilab.png
2011-09-20T21:15:19 [WARNING] libpng warning: Interlace handling should be turned on when using png_read_image
2011-09-20T21:15:20 [WARNING] libpng warning: Interlace handling should be turned on when using png_read_image
2011-09-20T21:15:20 [WARNING] libpng warning: Interlace handling should be turned on when using png_read_image

なんか警告でてる・・・それでも画像は出力できてる。

出力結果の一部(トリミング済み)はこんな感じ。

PhantomJS

ちなみに Firefox on Mac OS X でのスクリーンショットはこんな感じ。

Firefox

HTML Canvas + JavaScript による動的なコンテンツも画像化できる。


$ ./phantomjs rasterize.js http://www.nilab.info/lab/0/lineart_canvas.html 20110920_phantomjs_canvas.png

PhantomJS HTML Canvas : lineart by canvas
lineart by canvas

動的に生成した SVG によるコンテンツは画像化に失敗した。エラーは出なかったがSVGの部分が出力されない。


$ ./phantomjs rasterize.js http://www.nilab.info/lab/0/lineart_svg.html 20110920_phantomjs_svg.png

Flash コンテンツの画像化にも失敗。Flash の貼りつけてある部分が出力されない。


$ ./phantomjs rasterize.js http://www.nilab.info/z3/20070517_zlashdot_000610.html 20110920_phantomjs_flash.png
2011-09-20 21:44:48.051 phantomjs[3911:903] Error loading /Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore:  dlopen(/Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore: mach-o, but wrong architecture
2011-09-20 21:44:48.056 phantomjs[3911:903] Error loading /Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin:  dlopen(/Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin, 265): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin: no matching architecture in universal wrapper
2011-09-20 21:44:48.058 phantomjs[3911:903] Error loading /Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player:  dlopen(/Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player: no matching architecture in universal wrapper
2011-09-20 21:44:48.061 phantomjs[3911:903] Error loading /Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast:  dlopen(/Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast: mach-o, but wrong architecture

プラグイン・ライブラリのロードに失敗してる?
32/64ビットモードの問題なのかそれとも…

Silverlight コンテンツの画像化にも失敗。


$ ./phantomjs rasterize.js http://latlonglab.yahoo.co.jp/route/watch?id=e09cfdae3c805d3a4710844483664ec7 20110920_phantomjs_silverlight.png
2011-09-20 21:17:31.843 phantomjs[3885:903] Error loading /Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore:  dlopen(/Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/Silverlight.plugin/Contents/MacOS/agcore: mach-o, but wrong architecture
2011-09-20 21:17:31.853 phantomjs[3885:903] Error loading /Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin:  dlopen(/Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin, 265): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/QuickTime Plugin.plugin/Contents/MacOS/QuickTime Plugin: no matching architecture in universal wrapper
2011-09-20 21:17:31.857 phantomjs[3885:903] Error loading /Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player:  dlopen(/Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/Flash Player.plugin/Contents/MacOS/Flash Player: no matching architecture in universal wrapper
2011-09-20 21:17:31.861 phantomjs[3885:903] Error loading /Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast:  dlopen(/Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast, 262): no suitable image found.  Did find:
  /Library/Internet Plug-Ins/iPhotoPhotocast.plugin/Contents/MacOS/iPhotoPhotocast: mach-o, but wrong architecture

PhantomJS Silverlight
日本モンキーパークのゴーカート(二人乗り) - ルートラボ - LatLongLab

--load-plugins=yes オプションを指定しても結果は同じだった。

Ref.
- PhantomJS: Headless WebKit with JavaScript API
- QuickStart - phantomjs - 5-Minute Guide - headless WebKit with JavaScript API - Google Project Hosting
- BuildInstructions - phantomjs - Build Instructions - headless WebKit with JavaScript API - Google Project Hosting

tags: phantomjs javascript screenshot

Posted by NI-Lab. (@nilab)