wataメモ

日々のメモをつらつらと書くだけ

[7][Perl][WWW::Mechanize][Web::Scraper]WWW::MechanizeとWeb::Scraperを使ってみた

 APIを提供してくれていないサイトをAPI化する為にサーバサイドでHTTPリクエスト出して、帰ってくるHTMLを解析してしかるべきフォーマットで返すことがある。簡単な作業ならシェルで済ますことが出来るが、少し複雑になるとJavaで書いていた。Javaだと起動が若干遅いので、スクリプト言語で書けるようになっておきたいということでPerlWWW::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";
}

 これは色々応用出来そうなので良い感じだった。