JavaScript対応ロボット

多くのウェブサイトでJavaScriptが使われています。JavaScriptが動作しないウェブブラウザにも対応させることが、ウェブサイト制作における常識だったはずですが、最近はそうでもないようです。たとえば、みんな大好き英辞郎のウェブサイトでは、検索のためのボタン「英和・和英」にはJavaScriptだけが割り当てられているので、JavaScriptが動作しないブラウザでは使えません。次のコードでは、トップページは取得できても検索結果を取得できません。

use WWW::Mechanize;

$m = WWW::Mechanize->new();
$m->get('http://www.alc.co.jp/');
print $m->content;

動かない場合は、管理者になって(必要ならhttp_proxy, ftp_proxyを設定した状態で)「perl -MCPAN -e shell」とし、「install WWW::Mechanize」。テストに失敗するようなら、とりあえず「force install WWW::Mechanize」。

ウェブから情報を集めるために簡単なロボットを作ろうとするときなどに、このことは大きな障害になります。プログラム中でたいていのHTTPクライアントは(JavaのHTTP ClientやPerlのWWW::Mechanizeなど)、JavaScriptに対応していないからです。英辞郎はhttp://eow.alc.co.jp/単語/UTF-8/?ref=saというようなGETが使えるので実は問題ないのですが、すべてのサイトがこんなに親切なわけではありません。

ウェブアプリケーションのテストに使うSeleniumが、この問題の一つの解決策になります。

まず、Seleniumのサイトで、FirefoxのアドオンであるSelenium IDEをインストール、SeleniumのためのコントローラであるSelenium Remote Control (RC)をダウンロード・展開します。

FirefoxのツールメニューからSelenium IDEを起動して、(記録中にして)ブラウザを操作します。英辞郎の場合は、こんな感じになるでしょう。

このテストケースを自分が使いたいプログラミング言語用にエキスポートし(ファイル名はeijiro.plとする)、適当に修正します。Perlならこんな感じでしょうか。

use strict;
use warnings;
use Time::HiRes qw(sleep);
use Test::WWW::Selenium;
use Test::More "no_plan";
use Test::Exception;
<strong>use utf8;</strong>

my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                    port => 4444, 
                                    browser => "*chrome", 
                                    browser_url => "<strong>http://www.alc.co.jp/</strong>" );

$sel->open_ok("/");
$sel->type_ok("//input[\@name='q' and \@value='' and \@type='text']", "inquisitor");
$sel->click_ok("//input[\@value='英和・和英']");
$sel->wait_for_page_to_load_ok("30000");
<strong>print $sel->get_body_text();</strong>

これで完成です。Perl以外にも、JavaとGroovy、C#、PHP、Python、Rubyに対応しています。

java -jar selenium-server.jar

としてコントローラを起動し、

perl eijiro.pl

として実行すると、ウェブブラウザが自動的に起動し、英辞郎で検索、結果を表示してくれます(Ubuntuをプロキシサーバが必要な環境で利用している場合には、システムのプロキシを設定しておくといいでしょう)。「install WWW::Selenium」が必要かもしれません。テストに失敗する場合はとりあえず「force install WWW::Selenium」(「install CPAN」と「reload CPAN」が先かもしれません)。

アクセスするたびにウェブブラウザが起動するんじゃ遅くて使い物にならないと思うかもしれませんが、eijiro.plに相当するスクリプトを起動しっぱなしにしておいて、そこに対して何らかの方法で命令を渡していくように実装すれば、簡単なJavaScript対応ロボットになるでしよう。やっつけ感が気になる人は、ロボットの本体を置き換え可能に設計しておいて、あとで真面目に作り直してください。