Hatena::ブログ(Diary)

ダウンロードたけし(寅年)の日記 このページをアンテナに追加 RSSフィード Twitter

2007-10-26 HTML::Feature

HTML::Feature - 重要部分を抽出するモジュール -

以前からCPANで公開していたモジュールがあるんですが、日本語での解説ドキュメントがなかったのと、最近大幅にブラッシュアップしたので、せっかくなので紹介記事を書きます。

HTML::Feature - Extract Feature Sentences From HTML Documents

「えいちてぃえむえる::ふぃーちゃー」と読みます。

ブログやニュース記事など様々なHTML文書から「重要部分」を推測して抽出してくれる perl モジュールです。

「重要部分」とはいわゆる「本文」のことですね。本文抽出とか焦点抽出とか色々な言い方があるかと思いますが、まぁ要するに特徴的な部分を推測して抽出するわけです。

どういうものか。

例えばブログ記事からヘッダーやフッター、その他のナビゲーションブロックを除いた「記事らしき部分」だけを切り取りたい、とします。

ぱっと思いつくのは「特定のコメントタグにはさまれた部分を正規表現ですっぽりと抜く」ようなことを考え付きますが、もちろんお望みのコメントタグが世の中のHTML文書に入っているとは限りません。というか、期待するコメントタグに本文が挟まれているなどという都合のよいことはまずありえません。

そこでもう少し頑張ってみて「形態素解析してからTF/IDFで単語の重みを計算して重要なキーワードが含まれているテキスト部分を候補とする」というような方法が思い浮かびます。しかしこれにも落とし穴があります。形態素解析器がそもそもどこの国の言葉にあわせて作られているかによって、解析できるHTMLドキュメントの種類が決定されてしまいます。要するに日本語で形態素解析したら外国語のサイトは対象外になってしまう、ということです。当たり前の制約事項と言えばそれまでのことなんですが、とはいえ外国語のサイトも対象にしたいと思うとこの方法ではちょっと大変です。

HTML::Featureにはそれらの制約事項がありません。

HTMLの「構造」を解析して重要そうな部分を推測する仕組みになっています。

どういうロジックなのかは後述するとして、HTML::Featureはどこの国のサイトでも、また事前に特定のコメントタグなどを仕込んでおくような努力をせずとも、重要部分が抽出できます。

使い方

こんな感じ

use HTML::Feature;

my $feature = HTML::Feature->new;
my $result = $feature->parse("http://hogehoge.com");
print $result->text();

これでhogehoge.comの需要部分が抽出できます。parse()に渡すのはURLでも良いし、HTMLドキュメントそのものでも良いし、HTTP::Responseオブジェクトでも良いです。

ほかにも色々な呼び出し方があるので詳しくはCPANをみてください。

http://search.cpan.org/~miki/HTML-Feature-2.0.2/

利用シーン

クローラで集めてきたHTMLドキュメントをDBに突っ込む前のフィルターとして利用したりします。

検索エンジンや意味解析系のシステムで利用すると、解析精度がぐんと高まる、はず。たぶん。

仕組み

HTML::Featureは内部でHTML::TreeBuiderを使ってHTMLを構造木にした上で、各ノードを総なめにしながら、独自のロジックスコアリングしていきます。最終的にもっともスコアの高かったノードが「重要部分」ということになります。


で、肝心のスコアリングのロジックですが、実はとてもシンプルです。

- タグとテキスト部分のバイト数を比較して「テキスト率」が高いほど重要部分の可能性が高い

- HTMLタグの階層が深い部分であるほど、重要部分である可能性が高い

- HTML文書のなかでそのノードが登場する順序が早いほど、重要部分である可能性が高い

この3項目で各ノードを計算していくと、意外と簡単に重要部分があぶり出されてきます。

ほとんどの方が「え、こんなんで重要部分が抽出できんの?」と思われるかと。

実際にはHTML::Featureの抽出精度は7〜8割ってところです。

ブログやニュース記事のような本文部分が明確にある文書は得意ですが、ポータルサイトのトップページのように記事部分があまりなくてほとんどリンクばかりのサイトは苦手です。

まぁ当たるも八卦当たらぬも八卦といったところではありますが。

興味のある方はぜひ試してみてください。


Special Thanks to Daisuke Maki !!

通りすがり通りすがり 2010/06/08 10:01 便利なモジュールですね。
バグと思われますが、
my $f = HTML::Feature->new(user_agent => 'Mozilla/5.0');
などと user_agent を指定するとエラーになります。

Feature/Feature.pm
sub _setup {
my $self = shift;
my $c = $self->context;
my $fetcher = LWP::UserAgent->new;
my $config = $c->config;
if ( $config->{user_agent} ) {
$fetcher->user_agent( $config->{user_agent} );
}

$fetcher->user_agent( $config->{user_agent} );は
$fetcher->agent( $config->{user_agent} );
ではないしょうか?

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証