わかってしまえば単純なことでした。
1
|
process 'a[href=~/\.jpe?g$/]', 'urls[]' => '@href';
|
XPathでも同じようにできます。
1
|
process '//a[@href =~ /\.jpe?g$/]', 'urls[]' => '@href';
|
Web::Scraperにはフィルタの概念があって、取得してからごにょごにょできるので、そっちのほうばかり調べていました。
例えば以下のようなHTMLの場合、そのまま取得すると、前後に改行が入ってしまいます。
1
2
3
|
<title>
タイトルなのだ
</title>
|
で、それを取得する時に、前後の改行を削除してやることができます。
1
|
process 'title', 'title' => ['TEXT', sub { s/^\s+//o; s/\s+$//o; } ];
|
こういう機能をフィルタと呼んでいます。
その機能を先に知ったので、取得したあとに拡張子を調べてマッチした場合だけ追加する、という方法を探していたのですが、考えてみれば、取得してからきれいにするよりも、最初からきれいに取るほうがいいですね。
以上を踏まえて書き直したのが以下のコード。
ついでだったので、Acme::PerlTidyを使って、自動的にコードの整形をしてもらいました。
実行時には不要なので、削除して使ってもまったく問題ありません。
CPAN:☼ 林永忠 ☼ / Acme-PerlTidy - search.cpan.org
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
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;
}
|