WWW::Mechanizeで入力フォームにない項目を送信するには
例えばWebで蔵書検索を行う館で元々ISBN検索出来る機能をフォームを変更することで検索機能を殺している場合に無理矢理Mechで送信すると
$mech->select('code_genre1', '2'); $mech->submit_form( fields => { 'code_value1' => $isbn, } );
当然の事ながらエラーになる
Input "code_genre1" not found at ff.pl line 76
No such field 'code_value1' at /usr/local/lib/perl5/site_perl/5.8.8/WWW/Mechanize.pm line 1371
フォームにない項目をセットするとエラーになるという事は、フォームにある項目ならOK
同じパッケージでISBN検索機能がある館にmechをかけてDumpすれば該当項目が表示される
bless( { 'current' => 0, 'menu' => [ { 'seen' => 1, 'value' => '0', 'name' => 'foo', }, { 'value' => '2', 'name' => 'bar' } ], 'name' => 'code_genre1', 'type' => 'option' }, 'HTML::Form::ListInput', ), bless( { 'maxlength' => '40', 'value_name' => '', 'value' => '', 'name' => 'code_value1', 'type' => 'text', 'size' => '30' }, 'HTML::Form::TextInput', ),
この二つを$mech->{form}->{inputs}*1にpushしておくと、エラーにもならずキチンと検索結果が帰ってくる。
あとはscrapeするだけなのだがprocessを複数回指定するのが面倒だったり、ここで変数にセットしないでサブルーチンを呼ぶだけが出来なかったりと困っていたところ
http://perl-mongers.org/2008/07/mechanize-scraper.htmlのブックマークコメントに
$scraper->scrape(\$mech->content) すればいいだけだからほとんどかわらないんだけど。
http://b.hatena.ne.jp/miyagawa/20080731#bookmark-9489173
とのコメントが
# 複数回process my $hoge =scraper { process 'XPATH1', 'foo' => '@href'; process 'XPATH2', 'bar' => 'TEXT'; }->scrape(\$mech); # サブルーチン呼ぶだけ scraper { process 'XPATH3', 'buzz' => ['@href', \&fizz]; }->scrape(\$mech);
素直にこんな感じで記述できた
備考
自分がやろうとしているような場合は
-
- 分館情報がない場合WWW::Mechanizeで特定のリンクを洗い出す
- 分館情報がある場合WWW::Mechanizeで特定のリンクを洗い出してリンクを踏む、結果をWeb::Scraperに渡して分館情報を洗い出す
を基本に判りやすくて楽な方法を柔軟に使っていけばいいんじゃないかという結論
*1:WWW::Mechanize::Pluggable::Web::Scraperの場合は$mech->{Mech}-{form}-{inputs}