changes.xmlのおさらい

はてなダイアリーがchanges.xmlの出力を始めたらしいので、おさらい。

まずは仕様。→ http://newhome.weblogs.com/changesXml

changes.xmlはweblogs.comが出していた、とてもシンプルなXMLで、更新されたURLのリストを配信するためのもの。単にURLだけを並べただけのものなので、なんかしようと思ったら自分で何とかしなければならないんだが、逆に言えばURLのリストという単純な価値があるとも言える。出力側では、提供情報が少ないしフォーマットもらくちんなので、結構気軽に出せるもののような気がする。実際、PingBadgeでも初期から出しているフォーマットの一つだ。

じゃ、実際どう使うか。まぁ、アグリゲータを作るときのネタの一つ、というのは、間違いないが。もうちょっと手軽に作れるものということで、ランダムリンクを作ってみた。

はてなダイアリーランダムジャンプ (ネーミングセンス無し)

中身は簡単、単純にchanges.xmlを読んで、適当なURIを選び、Locationヘッダで飛ばすだけだ。実際には2つのパートに別れていて、cronで定期的にリストを取得するクローラーと、実際にジャンプを行うCGIである。

#!/usr/bin/perl -w

# # Crawler # #

use strict;
use Storable 'lock_store';
use LWP::UserAgent;

my $changesXml = 'http://d.hatena.ne.jp/changes.xml';
my $store_file = '/Users/a_aql/Sites/hcx/store.db';

# # # # #

my @array;

my $content = LWP::UserAgent->new->get( $changesXml )->content;
while( $content =~ m|^?s*<weblog name="(.*?)" url="(.*)" when=".*" />?s*$|mg ){
	push @array, { name => $1, uri => $2 };
}

lock_store ?@array, $store_file;

exit;
#!/usr/bin/perl -w

# # Random Jump # #

use strict;
use Storable 'lock_retrieve';

my $store_file = '/Users/a_aql/Sites/hcx/store.db';

# # # # #

$ENV{'QUERY_STRING'} = '' unless $ENV{'QUERY_STRING'};
my $array = lock_retrieve $store_file;

if( $ENV{'QUERY_STRING'} eq 'display' ){
	my $item = $array->[ int rand $#{$array} ];
	print "Content-Type: text/plain;charset=utf-8?n?n";
	print "NAME: ", $item->{name}, "?n";
	print "URI : ", $item->{uri};
}
elsif( $ENV{'QUERY_STRING'} eq 'list' ){
	print "Content-Type: text/plain;charset=utf-8?n?n";
	foreach my $item ( @$array ) {
		print "NAME: ", $item->{name}, "?n";
		print "URI : ", $item->{uri}, "?n?n";
	}
}
else{
	print "Location: ", $array->[ int rand $#{$array} ]->{uri}, "?n?n";
}
exit;

XML::Parserでパースするのももちろん良いが、この程度なら正規表現で十分。例えばURIを取得した後そのURIの内容をGETして、さらにRSS Auto DiscoveryでRSSを見つけXML::RSSでパース、なんて流れなら、どちらにせよXML::Parserを使うわけだし使っても良いとは思うし、いろんなchanges.xmlに対応させようとするとアトリビュートの順番だとか面倒なんだが、単にこういう使い方ならこれで良いだろう。

さて、じゃあこれで遊んだら次は何か。『動的ウェブリング』かな。これもRingBadgeで実績があるので、結構軽くできる。つーわけで、次はそれ。