サイトのクローリングにはScrappyがすごくいいかもしれない

クローリング楽しいですよね!


perlで高速にクロールしたいのであればGunghoなど使うのがいいかもしれませんが、
基本手軽にやりたいことが多いので
WWW::Mechanize+Web::Scraper
という組み合わせでクロールするのが定番でした。


しかしたまたま Scrappy を知り、
少し触ってみたところすごくいいのではないか!?と思い
記事にしてみました。*1

基本系(crawlコマンドを利用する場合)

my  $scrappy = Scrappy->new;    
$scrappy->crawl('1.クロールするルートURL',
    '2.URLにマッチするパス' => {
        '3.コンテンツにマッチするxpath or CSSセレクタ' => sub {
            my ($self, $item) = @_;
            # 4.キューに追加
            $self->queue->add($item->{href});
        }
    },
);

こんな構成になります。

  1. まずクロールするルートを指定し、
  2. その下にURLのパスを記述します。
  3. あとは普通にxpathCSSセレクタスクレイピングすることが可能です(Web::Scraperと同じ記述が可能)。
  4. また、自身のキューにURLをaddすることでcrawl対象のジョブキューに追加されます。
  5. crawlはキューからURLを取り出して処理を繰り返します。

例について

SYNOPSISも理解しやすいものになっていますが、
もう少し例を増やしてみます。

例その1:はてなフォトライフから画像ぶっこぬき


ルートURL = http://f.hatena.ne.jp/hotfoto

1ループ目
  1. パスが「/hotfoto」にマッチするので 11行目の処理が実行されます。
  2. スクレイピングでエントリURLを抜き出して、それをキューに突っ込みます。
2ループ目
  1. キューにaddされたURLは「'/:user/:id'」にマッチするので19行目の処理が実行されます*2
  2. 画像のURLをスクレイピングして、ローカルのtmpフォルダに画像を保存します。

例その2:はてぶのトップからperlタグをたどってエントリのリンク先からテキストのみ抽出


ルートURL = http://b.hatena.ne.jp/

1ループ目
  1. パスが「/」にマッチするので 13行目の処理が実行されます。
  2. スクレイピングで「タグ一覧」へのURLを抜き出して、それをキューに突っ込みます。
2ループ目
  1. パスが「/t」にマッチするので 20行目の処理が実行されます。
  2. スクレイピングで「perlタグ」へのURLを抜き出して、それをキューに突っ込みます。
3ループ目
  1. パスが「/t/:tag」(a) にマッチするので 28行目の処理が実行されます。
  2. スクレイピングで「ブログエントリ」へのURLを抜き出してリンク先のテキストをprintします。
    ここで新しくScrappyのインスタンスを呼び出しているのは、別サイトにリンクする可能性もあるためです。
    今回の場合はScrappyである必要もないため、普通にLWPなどでgetしても良いでしょう。
  3. スクレイピングで「次へ」リンクを抜き出して、それをキューに突っ込みます。このURLは (a) にマッチするので、「次へ」リンクがある限り再度ループします。

ドキュメント

http://search.cpan.org/~awncorp/Scrappy-0.94111610/lib/Scrappy.pm.bak
他にもいろんな機能があるのでご参照ください。
プラグイン機能もあるようですね。


いままでの知識はそのまま使えますし、なにより読みやすいのがいい!
階層構造に似たコーディングスタイルのため
あとから見たときに何をやっているのか一目瞭然です。


クローリングするときはしばらくこのモジュールを使ってみます!

*1:つまりそんなに使い込んでいない

*2:例:http://f.hatena.ne.jp/border514/20110701140005