大の大人が雁首そろえてソースコードを読むのって馬鹿馬鹿しくね?

読むのが楽しいソースコードなら、どんどん読めばいいじゃない。

ということで 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 としてタグ名ぐらいしか対応してないから、スクレイピングツールとしては使い物にならないよ!