scraper CLI で遊ぶ その2
pushing Web::Scraper 0.13 that has code generation and more examples in eg/
http://twitter.com/miyagawa/statuses/243570942
今度はコード生成だそうで。0.12 もチェックしていなかったので、あわせて新機能を確認。scraper CLI で遊ぶ - へたっぴ日記の続きっぽく。
今日はスクエニ@Yahoo!ファイナンスを題材に。
hetappi@violet ~ $ scraper 'http://quote.yahoo.co.jp/q?s=9684.t&d=t'
s コマンドで HTML ソースを表示。
scraper> s <html> <head> <title> Yahoo!ファイナンス - 9684.t </title> ... </body> </html> scraper>
いままではあらかじめブラウザかなんかでソースを確認してから実行していたけど、シェル上で簡単に確認できるようになったので便利!大きなものは見にくいので相変わらすブラウザで。
$tree 変数で解析済みのツリーが参照できる。
scraper> print $tree, "\n" HTML::TreeBuilder::XPath=HASH(0x109f79fc)
自分で好きにいじっちゃって!ってことでしょうか。複雑で XPath で書けない(もしくは書き方がわからない…)時とかも使える。
scraper> system "wget $_->{src}" for grep { my $f = $_->{src}; $f =~ s!.+/!!; !(-f $f); } $tree->findnodes('//img')
前からだけどこんなのもある。普通使わないだろうけど細工?する時に使える。眠くなかったら最後に書く。眠いのでそのうち書く。
scraper> print $scraper, "\n" Web::Scraper=HASH(0x108b5d84) scraper> print $scraper->__ua, "\n" LWP::UserAgent=HASH(0x109ddd08)
WARN は激しく便利。XPath や CSS セレクタを修正しながらさっくり確認できる。
scraper> process '//table[@border="1"]/tr[2]/td[1]', WARN; <td colspan="2" nowrap>取引値<br />9/3 <b>3,570</b></td> scraper> process '//table[@border="1"]/tr[2]/td[1]/b', WARN; <b>3,570</b> scraper>
で、 c コマンド。最後の入力(d や y などのコマンドは除く)から実行可能なコードを生成。
hetappi@violet ~ $ scraper 'http://quote.yahoo.co.jp/q?s=9684.t&d=t' scraper> process '//table[@border="1"]/tr[2]/td[1]/b', price => 'text' scraper> y --- price: '3,570' scraper> c #!/usr/bin/perl use strict; use Web::Scraper; use URI; my $stuff = URI->new("http://quote.yahoo.co.jp/q?s=9684.t&d=t"); my $scraper = scraper { process '//table[@border="1"]/tr[2]/td[1]/b', price => 'text'; }; my $result = $scraper->scrape($stuff);
XPath を修正していき正しく指定できたら 最後に c コマンドで実行用コードを生成する。あとは抽出結果を好きなよう編集すればよい。
c all で全ての入力からコードを生成することも。
scraper> process '//table[@border="1"]/tr[2]/td[2]/font', diff => 'text' scraper> y --- diff: -20 (-0.56%) price: '3,570' scraper> c all #!/usr/bin/perl use strict; use Web::Scraper; use URI; my $stuff = URI->new("http://quote.yahoo.co.jp/q?s=9684.t&d=t"); my $scraper = scraper { process '//table[@border="1"]/tr[2]/td[1]/b', price => 'text'; process '//table[@border="1"]/tr[2]/td[2]/font', diff => 'text'; }; my $result = $scraper->scrape($stuff); scraper>
もう便利すぎ。