問題が一つ。添削してくださったパッチだとおろろ...process '//li/node()[4]', 'title' => sub {$_->string_value;};
となっているのですが、4番目とは限らないんです。
たとえば、
http://www.cisco-records.co.jp/html/item/004/010/item393180.html
は何曲か試聴サンプルがないために、この処理だと取得できないです。
これはtext()でTextNodeを参照するしかないですね。
ただ、text()では改行等のゴミまで拾ってしまうので、以下のようにnormalize-space()で空文字ノードを省いています。
もしかすると、node()[2]も同じように修正した方がいいかもしれませんね。
#!/usr/bin/perl
use strict;
use warnings;
use Web::Scraper;
use URI;
use YAML;
use Data::Dumper;
my $uri = shift;
my %scraper;
$scraper{'link'} = scraper {
process 'a', 'name' => 'TEXT';
process 'a', 'uri' => '@href';
result qw/name uri/;
};
$scraper{'genre'} = scraper {
process '//a[1]', 'top' => $scraper{link};
process '//a[2]', 'style' => $scraper{link};
result qw/top style/;
};
$scraper{'track'} = scraper {
process '//li/text()[normalize-space(.)!=""]', 'title' => sub {
my $s = $_->as_XML;
$s =~ s/\s+$//;
return $s;
};
process 'li>a', 'uri' => '@href';
result qw/title uri/;
};
$scraper{'item'} = scraper {
process 'td.de_title', 'title' => 'TEXT';
process 'td.de_artist', 'artist' => 'TEXT';
process 'td.nm_jacket>img', 'image' => '@src';
process 'td.de_price', 'price' => 'TEXT';
process 'td.de_label>a', 'label' => $scraper{link};
process 'td.de_genre', 'genre' => $scraper{genre};
process 'td[headers="de_format"]', 'format' => 'TEXT';
process 'td[headers="de_release"]', 'release' => 'TEXT';
process 'td[headers="de_country"]', 'country' => 'TEXT';
process 'td[headers="de_sheet"]', 'sheet' => 'TEXT';
process 'td[headers="de_arrival"]', 'arrival' => 'TEXT';
process 'td[headers="de_nomber"]', 'number' => 'TEXT';
process '//p[@class="de_star"]/node()[2]', 'star' => 'TEXT';
process 'ul[id="de_sound"]>li', 'tracks[]' => $scraper{track};
result
qw/title artist image price label genre format release release country sheet arrival number star tracks/;
};
my $item = $scraper{'item'}->scrape( URI->new($uri) );
warn Dump $item;
あと、ブックマークコメントで
コールバック渡しだと相対URLの展開がされないのは僕だけ?との事ですが...少し調べてみた所Web::Scraper側でパッチが必要かもしれません。
以下svn/trunk(rev2351)からの差分です。
Index: lib/Web/Scraper.pm
===================================================================
--- lib/Web/Scraper.pm (revision 2351)
+++ lib/Web/Scraper.pm (working copy)
@@ -152,12 +152,12 @@
local $_ = $node;
return $val->($node);
} elsif (blessed($val) && $val->isa('Web::Scraper')) {
- return $val->scrape($node);
+ return $val->scrape($node, $uri);
} elsif ($val =~ s!^@!!) {
my $value = $node->attr($val);
if ($uri && is_link_element($node, $val)) {
require URI;
- $value = URI->new_abs($value, $uri);
+ $value = URI->new_abs($value, $uri)->as_string;
}
return $value;
} elsif (lc($val) eq 'content' || lc($val) eq 'text') {