こういうの無いかなぁと思ってました。
例えば任意のサイトのサマリを作りたい時、HTMLをテキスト化して一定文字数で削る訳ですが、どこからどこまでが本文かはそのサイト製作者の意図する所であってなかなか難しい処理かと思います。
今回ご紹介するHTML::ExtractContentはHTMLの内容を判断しコンテンツの本文らしき部分を抜き出せる凄いモジュールです。
ソースを見ましたがテキストに含めるかどうかの閾値が設定されており、かつ句読点まで判断しています。ソースはutf-8で書かれており、おそらく作者は日本人(もしくは日本通)かと思われます。
試しに先日の記事URLから本文を抜き出してみたいと思います。
use strict;
use warnings;
use HTML::ExtractContent;
use LWP::UserAgent;
my $agent = LWP::UserAgent->new;
my $res = $agent->get('http://perl-mongers.org/2008/09/template-refine.html');
my $extractor = HTML::ExtractContent->new;
$extractor->extract($res->decoded_content);
print $extractor->as_text;
コードもこれだけ。そして実行結果。
Template::Refineというモジュールを見つけました。リンク先にある通り、ruleを使うことで簡単にテンプレートの値を置き換える事が出来ます。このモジュールの良い所は、テンプレートファイルにテンプレートエンジン専用の識別子を記述しなくて良い所。どうやって指定するかというと、XPathを使います。リンク先から引用すると
my $username = 'Test User';
my $rule = simple_replace {
my $node = shift;
return replace_text $node, $username;
} '//*[@class="username"]';
といった感じにルールを決め
$frag = $frag->process($rule);
say $frag->render;
と実行する事でテンプレートへの反映が行われます。まるでWeb::Scraperの様ですね。
今日はサンプルとして、美輪明宏のチンコの有無を返すAPIから得た結果をテンプレートに反映してみたいと思います。
まずテンプレート
<p>美輪明宏にチンコは...<span class="miwa">...</span>。</p>
確かにテンプレート専用の識別子は使用していません。そしてperlのコード
use strict;
use warnings;
use Encode;
use Perl6::Say;
use LWP::Simple;
use JSON;
use Template::Refine::Fragment;
use Template::Refine::Utils qw(replace_text simple_replace);
my $miwa = from_json(get "http://dzfl.jp/mojo/");
my $rule = simple_replace {
my $node = shift;
return replace_text $node, encode_utf8($miwa->{miwa} ? 'ある' : 'ない');
} '//*[@class="miwa"]';
my $frag = Template::Refine::Fragment->new_from_file('template.html');
print $frag->process($rule)->render;
HTMLのmiwaというクラス属性を持ったノードに対して"ある"/"ない"というテキストで置換しています。
簡単ですね。テンプレートエンジン専用の識別子を使用しないので、HTMLの属性値さえ決めておけば、テンプレートの殆どをデザイナさんに任せてしまう事も出来る様になります。
すばらしいですね。
ちゃんと本文が取れています。ヘッダ部やページ右にあるナビゲータの文字は含まれていません。
すばらしいですね。他のアプリケーションにも簡単に取り込めそうですし期待が膨らみます。
どなたかこれを使ったウェブサービスを作ってみませんか。



Leave a comment