たろマーク (はてなブックマーク)
-
[ javascript ][ test ] Rspec ライクな Javascript テストフレームワーク
-
[ ezpublish ] eZ のデータソースを CakePHP で使うためのアダプタ。Rails とか Django にこれを移植すれば!
-
[ iquestioner ]
-
[ ruby ]
-
[ lazy-people ] おつでしたー
■ 勝手に記事取得 その2
RSS や Atom などのフィードを取得する際にサーバや帯域に余計な負荷をかけないためには、クライアント側でキャッシュしてやって Last-Modified ヘッダを正しく解釈するとよい、というか今後のフィードクライアントはそのように振舞うべきというのが世の中のコンセサンスです。
なるほどなぁってことで、勝手に記事取得のスクリプトをあえて URI::Fetch は使わずに LWP の mirror 使って作り直してみた。
#LWP::UserAgent で UA の定義とかしてみたかったのもあるし(゚ロ゚;)
本体。
#!/usr/bin/perl
# $Id: rss2html.pl,v 0.2 2005/04/25 19:56:29 taro Exp $
use strict;
use warnings;
use Digest::MD5 qw(md5_hex);
use Date::Parse;
use LWP::UserAgent;
use XML::RSS;
use Template;
# キャッシュディレクトリ
my $cache_dir = "/path/to/rss";
# テンプレートファイル
my $tmpl = '/path/to/rss.tmpl';
# 出力先
my $txt = '/path/to/rss.txt';
# 取得する RSS のリスト
my @urls = ('http://sky.taro-web.com/index.rdf');
my $ua = LWP::UserAgent->new;
$ua->agent('Taro RSS Aggregater/0.2');
my %data;
foreach my $url ( @urls ) {
my ($date,$rss) = get_rss($url,$cache_dir,5);
$data{$date} = $rss;
}
my @data;
my $i = 0;
foreach my $key ( reverse sort keys %data ) {
$data[$i] = $data{$key};
$i++;
}
my $tt = Template->new({ABSOLUTE => 1}) or die Template->error(), "\n";
my $output;
$tt->process( $tmpl,
{ data => \@data },
\$output,
) or die $tt->error();
utf8::encode($output);
open (TXT, "> $txt") or die "Can't open file $txt:$!";
print TXT $output;
close(TXT);
sub get_rss {
my ($url,$dir,$max) = @_;
if ( !$max ) { $max = 5; }
my $digest = md5_hex($url);
my $cache = "$dir/$digest.xml";
$ua->mirror($url, $cache);
my $rss = XML::RSS->new();
my $date;
eval {
$rss->parsefile($cache);
};
if ( $@ ) {
$date = '';
return ($date,$rss);
}
if ( $rss->{channel}->{dc}->{date} ) {
$date = Date::Parse::str2time( $rss->{channel}->{dc}->{date} );
} elsif ( $rss->{channel}->{pubDate} ) {
$date = Date::Parse::str2time( $rss->{channel}->{pubDate} );
} elsif ( $rss->{channel}->{lastBuildDate} ) {
$date = Date::Parse::str2time( $rss->{channel}->{lastBuildDate} );
} elsif ( $rss->{items}->[0]->{dc}->{date} ) {
$date = Date::Parse::str2time( $rss->{items}->[0]->{dc}->{date} );
} else {
$date = '0000000000';
}
return ($date,$rss);
}
テンプレート
[% FOREACH d = data %] <h3><a href="[% d.channel.link | uri | html %]" target="you">[% d.channel.title | html %]</a></h3> <p>[% d.channel.description | html %] <ul> [% FOREACH i = d.items %] [% LAST IF loop.count > 5 %] <li><a href="[% i.link | uri | html %]" target="you">[% i.title | html %]</a></li> [% END %] </ul> </p> [% END %]
Date::Parse がかなり便利なことを思い知らされてみたり。
あちこちもっさりしてるのはご愛嬌で。
ウチは SSI で Include してるけど、
テンプレを Javascript 風味にして、.js って拡張子とかで保存すると、
Javascript として本文中に Include できると思う。
Digest::MD5 使って、キャッシュファイル作ったのはこの辺参考にさせていただきました。というか、そのままですが(゚ロ゚;)
2005/04/25 ちょっと、Versionうp
トラックバック
このエントリーのトラックバックURL:
http://vkgtaro.jp/cgi-bin/mt/mt-tb.cgi/333




