昨日のエントリ、'Weblogs.Com Ping の Perl による実装' でも少し触れましたが、Weblogs.Com は受信した Ping による更新情報を整理して changes.xml として公開しています。各種メタブログサービスはこの changes.xml に記述された情報を元に、ウェブログを巡回したり、ウェブログの更新時間を得たりいったことを行っています。
changes.xml の仕様は 'Weblogs.Com News : How changes.xml works' で公開されています。とてもシンプルな XML フォーマットです。ここでは、changes.xml を Perl で料理する方法を考えてみます。
changes.xml は以下のフォーマットになっています。
<?xml version="1.0"?> <weblogUpdates version="1" updated="Thu, 28 Aug 2003 15:46:09 GMT" count="1060670"> <weblog name="NDO::Weblog" url="http://naoya.dyndns.org/~naoya/mt/" when="2"/> <weblog name="Scripting News" url="http://www.scripting.com/" when="152"/> ... </weblogUpdates>
weblogUpdates 要素をルートとして、その子要素に weblog 要素がぶらさがっているという、非常に単純なつくりです。新しく更新されたものほど上に記述されます。weblogUpdates 要素のそれぞれの属性は、
一方、子の weblog 要素の属性は以下です。
Weblogs.Com の changes.xml には 3 時間以内に更新された(Ping を受け取った)ウェブログの一覧が掲載されています。
さて、この XML 文書を Perl で料理するわけですが、見ての通り単純なフォーマットなので、パーサーには XML::Simple を使うのが簡単だし相性も悪くないと思います。XML::Simple は XML 文書を読み込み、リストとハッシュでツリー構造を作ってくれる便利なパーサーです。
サンプルとして、それぞれのウェブログの更新時刻を出力する簡単なスクリプトを書いてみました。
#!/usr/local/bin/perl
use strict;
use warnings;
use XML::Simple;
use Date::Parse;
use Date::Format;
use LWP::Simple;
# use Data::Dumper;
my $content = LWP::Simple::get('http://www.weblogs.com/changes.xml');
my $parser = XML::Simple->new;
my $weblogUpdates = $parser->XMLin( $content,
KeyAttr => 'weblog',
ForceArray => 1);
# print Dumper $weblogUpdates;
my $updated = Date::Parse::str2time( $weblogUpdates->{updated} );
for my $weblog ( @{$weblogUpdates->{weblog}} ) {
print Date::Format::time2str("%c", $updated - $weblog->{when} ), "\t", $weblog->{name}, "\n";
}
LWP::Simple で Weblogs.Com から changes.xml を GET して、それを XML::Simple でパースしできあがったデータ構造から weblog 要素の属性が持っていた値を取得して計算して出力しています。
my $updated = Date::Parse::str2time( $weblogUpdates->{updated} );
の部分ですが、Date::Parse モジュールが提供する str2time() に weblogUpdates 要素の updated 属性の値 (つまり RFC 822時刻表記で記述された changes.xml の更新日時) を食わせています。str2time は時刻表記をパースしてエポック秒に変換してくれます。
updated 属性の値から各 weblog 要素の when 属性の値(秒)を引けば更新日時が(秒単位で)分かります。ここでは Date::Format の time2str で任意の時刻表記に整形して出力しています。
このスクリプトを実行すると、
08/29/03 01:56:04 Renesite 08/29/03 01:56:03 Cleos Weblog 08/29/03 01:55:58 deifls-weblog 08/29/03 01:55:53 Priscamor @ LiveJournal 08/29/03 01:55:52 The Welsh Tort @ LiveJournal 08/29/03 01:55:52 Amirartist418's blog @ PersianBlog 08/29/03 01:55:51 TECHFLUID ...
といった出力が得られます。changes.xml からは weblog の URL リストも作れるので、それをもとに巡回ロボットを書いてやれば、ブログコンテンツを集めるロボットなんかが書けるという仕組みです。
Simple is a best. ですね。
次は、受信した Ping をまとめて changes.xml として出力する方法について書こうと思います。