大の大人が雁首そろえてソースコードを読むのって馬鹿馬鹿しくね?
読むのが楽しいソースコードなら、どんどん読めばいいじゃない。
ということで pQuery.pm を読んでみたyp!
パッと見でわかりにくい部分はあるけど、ingy products にしてはそんなに変なことはやってないよ。Spiffy もつかってないしね!
my $my = {} sub pQuery { # (ry $my->{$self} = {}
のあたりとか、混乱するけど、このコードにはなんの意味もないみたいだよ!
引数として渡ってきたリファレンスとかをイジりたおしてるから、参照の概念がわかってないと混乱するよ!
まだ pQuery 自体が作りかけなので、試してみようと思っても、ほとんどなにも動かないよ!
とりあえず、CSS Selector を HTML::Selector::XPath+HTML::TreeBuilder::XPath で、それなりに動くようにしつつ、HTTP::Response::Encoding で decode してみたりする適当なパッチを書いてみたよ(主に Web::Scraper からのパクりだよ!)!
=== Makefile.PL ================================================================== --- Makefile.PL (revision 8391) +++ Makefile.PL (local) @@ -3,7 +3,10 @@ name 'pQuery'; all_from 'lib/pQuery.pm'; -requires 'HTML::TreeBuilder' => 0; +requires 'HTML::TreeBuilder' => 0; +requires 'HTML::Selector::XPath' => 0; +requires 'HTML::TreeBuilder::XPath' => 0; +requires 'List::Util' => 0; use_test_base; === lib/pQuery.pm ================================================================== --- lib/pQuery.pm (revision 8391) +++ lib/pQuery.pm (local) @@ -3,6 +3,9 @@ use warnings; use 5.006001; use HTML::TreeBuilder; +use HTML::Selector::XPath 'selector_to_xpath'; +use HTML::TreeBuilder::XPath; +use List::Util qw(first); use base 'Exporter'; # use XXX; @@ -11,7 +14,6 @@ our @EXPORT = qw(pQuery); -my $my = {}; my $lwp_user_agent; sub pQuery { @@ -21,7 +23,6 @@ sub new { my $class = shift; my $self = bless [], $class; - $my->{$self} = {}; if (not @_) { return $self; @@ -48,11 +49,20 @@ sub new_from_url { my $self = shift; my $url = shift; + require Encode; + require HTTP::Response::Encoding; my $response = $self->get($url); if (! $response->is_success) { return $self; } - return $self->new_from_html($response->content); + my @encoding = ( + $response->encoding, + ( $response->header('Content-Type') =~ /charset=([\w\-]+)/g ), + "latin-1", + ); + my $encoding = first { defined $_ && Encode::find_encoding($_) } @encoding; + my $html = Encode::decode( $encoding, $response->content ); + return $self->new_from_html($html); } sub new_from_html { @@ -118,7 +128,7 @@ my $selector = shift or return; my $elems = []; $self->each(sub { - _find_elems($_, $selector, $elems); + push @$elems, $_->findnodes( selector_to_xpath $selector ); }); return pQuery($elems); } @@ -176,22 +186,6 @@ } } -sub _find_elems { - my ($elem, $selector, $elems) = @_; - return unless ref $elem; - - if ($selector =~ /^\w+$/) { - if ($elem->{_tag} eq $selector) { - push @$elems, $elem; - - } - } - - for my $child (@{$elem->{_content}}) { - _find_elems($child, $selector, $elems); - } -} - 1; =head1 NAME
このパッチあてると、ABUI くんが http://abui.nowa.jp/entry/e9b8f13844 で
# h2.entry-titleとクラス名まで具体的に指定すると動いてくれなかった。。。
って書いてるような、CSS Selector の設定もちゃんとできるようになるよ!というか、pQuery-0.01 は、CSS Selector としてタグ名ぐらいしか対応してないから、スクレイピングツールとしては使い物にならないよ!