[7][Perl][WWW::Mechanize][Web::Scraper]WWW::MechanizeとWeb::Scraperを使ってみた
APIを提供してくれていないサイトをAPI化する為にサーバサイドでHTTPリクエスト出して、帰ってくるHTMLを解析してしかるべきフォーマットで返すことがある。簡単な作業ならシェルで済ますことが出来るが、少し複雑になるとJavaで書いていた。Javaだと起動が若干遅いので、スクリプト言語で書けるようになっておきたいということでPerlのWWW::Mechanizeを使ってみた。ちょっと古い環境だったのでPerl5.8.2しか入っていなく、WWW::Mechanizeが依存しているHTTP::Requestが必要としている5.8.8にアップグレード。Perlをインストール作業はよく考えれば初めてだった。
wget http://cpan.org/src/perl-5.8.8.tar.gz tar -xzvf perl-5.8.8.tar.gz cd perl-5.8.8 sh Configure -Dusethreads -Uinstallusrbinperl make make test make install
WWW::Mechanizeは基本的なHTTPのやり取り(HTTPメソッド、SSL、自動Cookie管理、プロキシ、認証)をサポートし、HTMLのフォームやらリンクやらをプログラマがHTMLを解析せずに扱うことが出来る。上手く書けば、解析側のHTMLのデザインが変わったぐらいではメンテナンスは要らなくなる。以下は公式のサンプルソース。
use WWW::Mechanize; my $mech = WWW::Mechanize->new(); $mech->get( $url ); $mech->follow_link( n => 3 ); $mech->follow_link( text_regex => qr/download this/i ); $mech->follow_link( url => 'http://host.com/index.html' ); $mech->submit_form( form_number => 3, fields => { username => 'mungo', password => 'lost-and-alone', } ); $mech->submit_form( form_name => 'search', fields => { query => 'pot of gold', }, button => 'Search Now' );
ログイン認証等をWWW::Mechanizeでやらせ、たどり着いた目的の画面のデータを解析する為に使用したWeb::Scraperが使ったが、これが秀逸だった。特徴としてはHTMLを解析するときにXPath形式とCSSセレクタ形式で指定出来る。使い慣れているCSSセレクタで指定出来るのは非常にありがたい。両方共使い方が分かったら、目的の画面のデータを返すAPIを作成するのに5分程度で作成できた。例えばどこかの静的画面を取ってきてtableタグで表示されているtdタグのデータを取得したいのであれば以下の様な感じ。
use Web::Scraper; use WWW::Mechanize; my $mech = WWW::Mechanize->new(); my $url = 'http://xxx.jp/yyy.html'; my $res = $mech->get( $url ); my $scrape = scraper { process 'td', 'td[]' => 'TEXT'; }->scrape($res->content); foreach my $d (@{$scrape->{td}}) { print $d . "\n"; }
これは色々応用出来そうなので良い感じだった。