わかってしまえば単純なことでした。
process 'a[href=~/\.jpe?g$/]', 'urls[]' => '@href';
XPathでも同じようにできます。
process '//a[@href =~ /\.jpe?g$/]', 'urls[]' => '@href';
Web::Scraperにはフィルタの概念があって、取得してからごにょごにょできるので、そっちのほうばかり調べていました。
例えば以下のようなHTMLの場合、そのまま取得すると、前後に改行が入ってしまいます。
<title>
タイトルなのだ
</title>
で、それを取得する時に、前後の改行を削除してやることができます。
process 'title', 'title' => ['TEXT', sub { s/^\s+//o; s/\s+$//o; } ];
こういう機能をフィルタと呼んでいます。
その機能を先に知ったので、取得したあとに拡張子を調べてマッチした場合だけ追加する、という方法を探していたのですが、考えてみれば、取得してからきれいにするよりも、最初からきれいに取るほうがいいですね。
以上を踏まえて書き直したのが以下のコード。
ついでだったので、Acme::PerlTidyを使って、自動的にコードの整形をしてもらいました。
実行時には不要なので、削除して使ってもまったく問題ありません。
CPAN:☼ 林永忠 ☼ / Acme-PerlTidy - search.cpan.org
use Acme::PerlTidy;
use strict;
use warnings;
use Web::Scraper;
use URI ();
use LWP::Simple qw(mirror);
use File::Basename qw(basename);
my $uri = URI->new("http://weblog.nqou.net");
my $scraper = scraper {
process 'a[href=~/\.jpe?g$/]', 'urls[]' => '@href';
result 'urls';
};
my $result = $scraper->scrape($uri);
foreach my $link ( @{$result} ) {
my $filename = basename($link);
mirror( $link, './images/' . $filename );
sleep 1;
}


コメントする