November 20, 2003

Monday Module ひとり - HTML::LinkExtor

[ Perl ]

Perl Hacker な人たちと IRC でチャットしていて、Monday Module とかやらないかっていう話が出ました。要は Photo Friday のパクリで、一週間に一回ネタ出ししてそれについてのエントリを書く、それの Perl スクリプト版。CPAN から適当なモジュールをピックアップして、それをお題として、何かスクリプトを書いてみたらどうだろうという。

面白いモジュールを見つけるのは誰がやるのとか、どうやってエントリを集約するのとか、過去ログはどういう扱いになるのとか、どこに設置するのとかまだ真面目に考えてはないのですが、コンセプトとしては結構面白いかなと思います。

そこでなんとなく予行演習してみます。名付けて "Monday Module ひとり" (劇団ひとりみたいだ) 。なんで Monday なんだというのは特に理由はなくて、語呂が良い (MM と略せるし)とか、月曜にこの話が出たとかそんな感じだったと思います。

ということで、

This week's challenge: "HTML::LinkExtor".

HTML::LinkExtor は HTML 文書の中からリンク文字列を抜き出して返してくれるモジュールです。

これと ping.bloggers.jp の changes.xml を組み合わせて、最近更新のあったウェブログからリンクを抜き出して数えて、多くリンクが貼られているページを抽出するというスクリプトを書きました。至極単純なスクリプトなので、実行結果はノイズだらけなのですが。

#!/usr/local/bin/perl
# changes.xml を元にリンクを数える
#
# Naoya Ito <naoya@naoya.dyndns.org>
# 2003.11.20 作成
use strict;
use warnings;
use HTML::LinkExtor;
use WebService::ChangesXml;
use LWP::Simple;
 
our %LINKS;
use constant URL => 1;
 
my $changes = WebService::ChangesXml->new('http://ping.bloggers.jp/changes.xml');
my $pings = $changes->find_new_pings(10800);
 
for my $ping (@$pings) {
    my $base = $ping->{url};
 
    my $content = LWP::Simple::get($base) or next;
    my $parser = HTML::LinkExtor->new;
    $parser->parse($content);
 
    my %seen = ();
 
    for my $link ($parser->links) {
	if (shift @{$link} eq 'a') {
	    # 相対パスは要らない
	    next if  ($link->[URL] !~ /^https?/);
 
	    # 絶対URLでもサイト内リンクは要らない
	    next if ($link->[URL] =~ /$base/);
 
	    # 同じサイトで同一リンクは要らない
	    next if (exists $seen{ $link->[URL] });
 
	    $LINKS{ $link->[URL] }++;
	    $seen{ $link->[URL] }++;
	}
    }
}
 
for my $url (keys %LINKS) {
    printf ("%d %s?n", $LINKS{$url}, $url) if ($LINKS{$url} > 3);
}

changes.xml のパースは自分で書いても良かったのですが、先日宮川さんが CPAN に上げた WebService::ChangesXml を利用しました。XML::Simple で XML のパーシングとそのデータ構造を抽象化したクラスです。便利です。

たくさんのサイトに HTTP リクエストを投げるので、本来は fork() するとかスレッドを使うとか、あるいは POE あたりを使うのがいいのですが、例によって面倒なのでそれはせずに、単純にシングル処理。

$ perl bloglinks.pl | sort -nr | more

とかして実行してやると、

84 http://www.movabletype.org
24 http://www.myblog.jp/
18 http://ping.bloggers.jp/
12 http://japan.cnet.com/
10 http://www.movabletype.org/
 9 http://yeah.myblog.jp/
 9 http://xtc.bz/
 9 http://www.zdnet.co.jp/
 9 http://www.watch.impress.co.jp/
 9 http://www.apple.co.jp/
 9 http://slashdot.jp/
 9 http://readmej.com/
 9 http://bulkfeeds.net/
 8 http://www.hotwired.co.jp/
 8 http://www.blogrolling.com/
 8 http://whatisthematrix.warnerbros.com/
 8 http://kotonoha.main.jp/2003/11/09yeah2003all.html
 8 http://itpro.nikkeibp.co.jp/
 8 http://coolsummer.typepad.com/kotori/
 7 http://yami.to/
 7 http://x51.org/
 7 http://www5.big.or.jp/%7Ehellcat/news/0311/17pic.html
 7 http://www2.diary.ne.jp/user/69964/
 7 http://www14.big.or.jp/~onmars/
 7 http://www.zakzak.co.jp/geino/n-2003_11/g2003111914.html
 7 http://www.zakzak.co.jp/geino/n-2003_11/g2003111812.html
 7 http://www.zakzak.co.jp/geino/n-2003_11/g2003111413.html
 7 http://www.zakzak.co.jp/
 7 http://www.wired.com/
 7 http://www.watch.impress.co.jp/av/docs/20031117/cci.htm
 7 http://www.vrnetcom.co.jp/weekly/index.html
 ...

こーんな感じの結果が。予想通りというか movabletype.org が飛び抜けてる。Powered by Movable Type のところのリンクに引っかかるんでしょうね。せかいのまんなか (止まっちゃってるなあ)とか blogmap みたくするには、精度を上げるためにノイズを除去するとか、ピンポイントで記事への URL だけを抽出するとか、似たような URL や同じページを指す事なる表現の URL とかをどうマージするかとか、サイトのリンクをいくつか辿って巡回(要はロボット)するとか色々考える必要があります。あくまで Monday Module なので、軽いノリで作ったという代物です。 :D

# ノイズの除去は二つのアーカイブを拾って diff すればいいんじゃないかと宮川さんがちらっと言ってまいました。

Posted by naoya at November 20, 2003 03:18 AM | トラックバック (7)  b_entry.gif
トラックバック [7件]
TrackBack URL: http://mt.bloghackers.net/mt/suck-tbspams.cgi/664
Monday Moduleふたり
Excerpt: NDO::WeblogのnaoyaさんがMonday Module ひとり - HTML::LinkExtorというエントリでMonday Moduleの予行演習をやってらっしゃったので、言い出しっぺは僕だし、やはり面白いとは思うので僕もスクリプト作ってみました。HTML::LinkExtorということで、HTMLからURLを抜き出...
Weblog: hail2u.net - Weblog
Tracked: November 20, 2003 05:55 AM
Monday Module さんにん
Excerpt: 最初にこの話を聞いたときはピンと来なかったんだけど、実際にやってみると面白いですねコレ。というわけで予行練習に私も参加してみました。
Weblog: UnknownPlace.
Tracked: November 20, 2003 04:43 PM
Monday Module
Excerpt: URL を指定すると、そこに含まれる画像と、HTML自体のサイズを合計する CGI スクリプトです。ユーザビリティテストや、携帯端末向けのページ作成でのサイズ容量制限チェックに便利でしょう。
Weblog: blog.bulknews.net
Tracked: November 20, 2003 11:28 PM
Monday Module
Excerpt: Kyoさんのいいだしっぺで、おもしろそうな企画が始まりました(引用元は NDO::Weblog です)。CPAN は普段あまり使わないので、勉強のために参加してみます。 NDO::Weblog: Monday Module ひとり - HTML::LinkExtor Perl Hacker な人たちと IRC でチャットしていて、Monda...
Weblog: bricklife.*
Tracked: November 21, 2003 03:37 AM
Monday Module - HTML::LinkExtor
Excerpt: Monday Module - HTML::LinkExtorでアサマシゴールド(謎)を実装。
Weblog: 行動記録
Tracked: November 21, 2003 05:07 AM
Monday Module -HTML::LinkExtor
Excerpt: kyoさんのモノマネでGO。
Weblog: Outside of mind
Tracked: November 22, 2003 10:59 PM
Monday Module(遅っ) HTML::LinkExtor
Excerpt: すっかり出遅れた(というか忘れていた)Monday Module HTML::LinkExtorの巻ですが、あまりぱっとしたものが思いつかなかったので、このモジュールの機能をコマンドラインから便利に使いましょうというネタで。
Weblog: MODULE.JP
Tracked: November 24, 2003 11:16 PM
コメント [0件]