拙著「FXはチャートで勝つ!」が発売されました。
FX(外国為替証拠金取引)でのチャートの読み方を解説しています。
自由国民社刊で、定価1,728円(消費税込み)です。
Webページのテストやスクリーンキャプチャに便利な「PhantomJS」
先日、twitterで@chacoさんと@riatwさんの以下のようなやり取りを見かけました。
@chaco Phantom.jsなるものが最近流行っているんだとか。
— Kentaro Suzukiさん (@riatw) 1月 11, 2013
そこで、PhantomJSについて調べてみました。
1.PhantomJSの概要
PhantomJSは、WebKitを組み込んだWebブラウザエミュレータのようなものです。
Webブラウザに対する一連の操作を自動化して、その結果を得ることができます。
自動化したい処理は、JavaScriptで記述します。
たとえば、以下のようなことを行うことができます。
- フォームの送信など、Webページに対する各種の動作テスト
- Webページに対してDOM操作等を行って結果を出力
- スクリーンキャプチャ
- リクエスト/レスポンスの調査
2.PhantomJSのインストール
PhantomJSは、Windows/Mac/Linux用のバイナリファイルと、ソースコードが配布されています。
一般的には、ご自分の環境に合ったバイナリファイルをダウンロードするのが簡単で良いでしょう(ただし、Linux版は依存関係がありますので要注意)。
Windowsの場合だと、ダウンロードしたZipファイルの中のphantomjs.exeが、実行ファイルです。
また、MacではZipファイルの中のbin/phantomが実行ファイルです。
3.スクリプトの基本
PhantomJSで実行するJavaScriptのひな形は、以下のようになります。
var page = require('webpage').create();
page.open(操作対象WebページのURL, function (status) {
各種の操作
phantom.exit();
});
openメソッドを実行すると、PhantomJS内部のWebKitがそのページにアクセスします。
そして、内部的にページの表示が終わると、openメソッドに渡したコールバック関数が実行されます。
その結果、コールバック関数の「各種の操作」の部分が処理され、開いたWebページに対する各種の操作が実行されます。
各種の操作は、pageオブジェクトのメソッドで表します。
主なメソッドとして、以下のようなものがあります。
| メソッド | 概要 |
|---|---|
| addCookie | Cookieをセットする |
| evaluate | Webページのコンテキストで関数を実行し、その結果を返す |
| includeJs | JavaScriptを挿入する |
| render | ページをキャプチャする |
| sendEvent | マウスやキーボードのイベントを送信する |
| uploadFile | ファイルをアップロードする |
スクリプトを作成したら、ファイルに保存します。
そして、ターミナルを起動し、phantomjsがあるディレクトリに移動して、「phantomjs スクリプトのファイル名」のコマンドを入力してスクリプトを実行します。
4.画面キャプチャの例
画面キャプチャを行うスクリプトの例として、Google/Yahoo/Bingのトップページをキャプチャするスクリプトを作ってみました。
先頭のURLとファイル名の代入部分を書き換えれば、他のWebページをキャプチャすることもできます。
var sites = [
{ url: 'http://www.google.co.jp/', image: 'google.png' },
{ url: 'http://www.yahoo.co.jp/', image: 'yahoo.png' },
{ url: 'http://www.bing.com/', image: 'bing.png' }
];
var captured = 0;
function capture(site) {
var page = require('webpage').create();
page.open(site.url, function() {
page.render(site.image);
console.log('captured ' + site.url);
captured++;
if (captured == sites.length) {
phantom.exit();
}
});
}
for (var i = 0, j = sites.length; i < j; i++) {
capture(sites[i]);
}
