Hatena::ブログ(Diary)

naoyaのはてなダイアリー

May 09, 2007

Web::Scraper

Today I've been thinking about what to talk in YAPC::EU (and OSCON if they're short of Perl talks, I'm not sure), and came up with a few hours of hacking with web-content scraping module using Domain Specific Languages.

Journal of miyagawa (1653)

使ってみたよ!

#!/usr/local/bin/perl
use strict;
use warnings;
use FindBin::libs;

use URI;
use Web::Scraper;
use Encode;
use List::MoreUtils qw/uniq/;

my $links = scraper {
    process 'a.keyword', 'keywords[]' => 'TEXT';
    result 'keywords';
}->scrape(URI->new(shift));

print encode('euc-jp', $_), "\n" for uniq @$links;
% perl scrape.pl http://d.hatena.ne.jp/hatenadiary/ | head -5
asterisk
techno
goth
プロフィール
アイコン

おおお miyagawa++。次いで http://d.hatena.ne.jp/secondlife/20060922/1158923779 にある Scrapi での例を Web::Scraper でやってみる。

#!/usr/local/bin/perl
use strict;
use warnings;
use FindBin::libs;

use URI;
use Web::Scraper;
use Encode;
use YAML;

my $links = scraper {
    process 'span.title > a:first-child', title => 'TEXT', url => '@href';
    process 'span.furigana', furigana => 'TEXT';
    process 'ul.list-circle > li:first-child > a', category => 'TEXT';
    result qw/title furigana url  category/
}->scrape(URI->new(shift));

warn encode('euc-jp', YAML::Dump($links));
% perl keyword_scraper.pl http://d.hatena.ne.jp/keyword/%BA%B0%CC%EE%A4%A2%A4%B5%C8%FE
---
category: アイドル
furigana: こんのあさみ
title: 紺野あさ美
url: /keyword/%ba%b0%cc%ee%a4%a2%a4%b5%c8%fe?kid=800

ばっちりですね。シンボルの書き方とかがちょっと違うところ以外は Ruby 版とほぼ等化。DSL 周りのドキュメントはまだないけどとりあえず scrapi のドキュメントを読めば ok! \(^o^)/

中の実装は HTML::TreeBuilder::Xpath + HTML::Selector::XPath で Xpath、シンボルテーブル hack で Perl DSL。HTTP::Response::Encoding が内蔵されてて取りに行く文字列の文字エンコーディングを気にしないでもいいのがささりげなくクライアントに優しい。ていうかコード短かいなあ、グレイト。

miyagawamiyagawa 2007/05/09 17:00 サンクスです。0.04 で scraper {} の返り値をWeb::Scraperオブジェクトに変えました。ので、クロージャを実行するかわりに ->scrape() メソッドを呼ぶように書き換えてくださいませ。

クロージャのほうがかっこよくて好きだったんだけど、こっちのほうがscrapi.rbとおなじAPIになるし、見た目わかりやすいということで。

また、明日になったら気が変わっているかもしれませんがw

naoyanaoya 2007/05/09 17:35 書き換えた!

この場合インタフェースは OO 風にするよりクロージャで DSL っぽさを残すほうがかっこいい気がしますね。

naoyanaoya 2007/05/09 17:35 DSLっぽさというか Hack 臭というか。

miyagawamiyagawa 2007/05/09 18:14 そうなんすよねえ。scrape(&)でコード渡してるので、クロージャが帰ってくるほうが直感的な気もするんだよなぁ。まあ、そのコードに引数がそのまま渡されて実行されるわけではないので紛らわしいっちゃ紛らわしいですが。

   2007/05/14 22:11 ポケットはてなで変換するサイトのMETA robots noindexを勝手に外さないでください。迷惑極まりないSPAM行為ですよ。