WWW::Mechanize と Web::Scraper を使って HTML からテキストを抽出して CSV を作成する Perl スクリプト - ablog
で scrape したのと同じようなページのテキストを scrape したいという要望があって、使いまわせるぞと思ったら。。。
ガーン!
テキストリンクじゃなくてボタンになっている。
HTMLソースを見てみると、
<input value="詳細" onclick="... ; if (...) { window.location.href='...'; } ;return false" type="button">
ということは、「window.location.href='...'」 部分から URL を抽出すればおkか。
id:otsune さんに教えて頂いた filter を使って、
my $list_scraper = scraper { process '/html/body/div/div[3]/table/tbody/tr/td/input[2]', 'link[]' => ['@onclick', sub {s/^.*window\.location\.href=\'(\?.+)\'.*$/$1/sg; } ]; };
としてみたらいけた。filer 便利というか Web::Scraper めちゃ便利!
#!/usr/bin/env perl use strict; use warnings; use WWW::Mechanize; use WWW::Mechanize::AutoPager; use Web::Scraper; use Text::CSV; use utf8; use Encode; my $list_scraper = scraper { process '/html/body/div/div[3]/table/tbody/tr/td/input[2]', 'link[]' => ['@onclick', sub {s/^.*window\.location\.href=\'(\?.+)\'.*$/$1/sg; } ]; }; my $detail_scraper = scraper { process '/html/body/div/div/form/fieldset/div/span', '1' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[2]/span', '2' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[3]/span', '3' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[4]/span', '4' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[5]/span', '5' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[6]/span', '6' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[7]/span', '7' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[8]/span', '8' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[9]/span', '9' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[10]/span', '10' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[11]/span', '11' => 'TEXT'; process '/html/body/div/div/form/fieldset/div[12]/span', '12' => 'TEXT'; }; my $mech = WWW::Mechanize->new; my $csv = Text::CSV->new; $mech->autopager->add_site( url => 'http://foo.ablog.co.jp/', nextLink => '//a[@title="Go to next page"]' ); $mech->get('http://foo.ablog.co.jp/foo-bar/login'); $mech->submit_form('fields', {'name', 'foo', 'password', 'foo'}); # login $mech->get('http://foo.ablog.co.jp/foo-bar/cs/'); # move to list page $mech->submit_form(); # submit search button my @url_list; while(){ my $list = $list_scraper->scrape($mech->content); # scrape list page push @url_list, @{$list->{link}}; # add urls to array $mech->get($mech->next_link); # move to next page last if ( $@ or !defined($mech->next_link) ); # quit if last page } open my $out_file, ">:encoding(utf8)", "list.csv" or die $!; foreach (@url_list) { $mech->get("http://foo.ablog.co.jp/foo-bar/$_"); # move to detail page my $detail = $detail_scraper->scrape($mech->content); # scrape detail page $csv->combine(@{$detail}{sort {$a <=> $b} keys %$detail}); # to csv print $out_file $csv->string . "\n"; # write a line to file } close $out_file; __END__