アンテナ作り

RSSを解釈できるようにアンテナ「なつみかん」を改造したときのメモです。CPANのXML::RSSを用いて少々修正を加え、実現しました

XML::RSS

インストール・メンテナンスはPerl/CPANを参照

XML::RSSの使い方が少しだけですが、RSS解析はXML::RSSにおまかせ (allabout)に書いてあります

はてなのHTTPサーバ仕様

よくわからないけどはてなはIEに対してはapplication/xmlを、なつみかんのhttpライブラリにはtext/htmlを返してくる。と思ったらはてなのhttpdはHEADに対してドキュメントのMIMEタイプを返さずtext/htmlを返していた。しょうがないからGETで対応

保守・運用・開発

実装

RSSを取得する作業をコーディングしたものの一部(Perl+CPAN)

use XML::RSS;
use DateTime::Format::W3CDTF;
use DateTime::Format::HTTP;

sub dtw3cdtf2epoch
{
    # W3CDTF to Epoch
    my $datestr = shift;
    my $dtw3cdtf = new DateTime::Format::W3CDTF;
    my $dt;
    eval { $dt = $dtw3cdtf->parse_datetime($datestr); };
    if($@) {
	print "    RSS Date String [$datestr] convert failed\n";
	return 0;
    } else {
	return $dt->epoch;
    }
}
sub dthttp2epoch
{
    # HTTPDATE to Epoch
    my $datestr = shift;
    my $dthttp = 'DateTime::Format::HTTP';
    my $dt;
    eval { $dt = $dthttp->parse_datetime($datestr); };
    if($@) {
	print "    RSS Date String [$datestr] convert failed\n";
	return 0;
    } else {
	return $dt->epoch;
    }
}

以下はContent-Type判定ですが、本来ならクロール先の設定ファイルで「RSS受信」などと指定するべき。

 if($tmp =~ /Content-Type:\s*(text\/xml|application\/rss\+xml|application\/xml)/i) {
   print "  MIME matched. read RSS\n";

XML::RSSを利用したRSSパースです

my $rss;
$rss = new XML::RSS;
eval { $rss->parse($bodytmp); };
if($@) {
} else {
  my $latest = 0;
  print "    parsing RSS successful.\n";
  
  # RSS1.0 channel dc:date
  my $rssversion = $rss->{'version'};
  if ($rssversion eq '2.0') {
      print "    RSS 2.0 not supported\n";
  } elsif ($rssversion eq '1.0') {
      if($rss->{'channel'}->{'dc'}->{'date'}) {
	  $latest = dtw3cdtf2epoch($rss->{'channel'}->{'dc'}->{'date'});
      }
      
      foreach my $item (@{$rss->{'items'}}) {
	  my $itemDate = 0;
	  
	  if($item->{'dc'}->{'date'}) {
	      $itemDate = dtw3cdtf2epoch($item->{'dc'}->{'date'});
	  } else {
	      print "    RSS DATE convert failed\n";
	  }
	  
	  $latest = ($itemDate > $latest)? $itemDate : $latest;
      }
  } elsif($rssversion eq '0.91') {
      if($rss->{'channel'}->{'pubDate'}) {
	  $latest = dthttp2epoch($rss->{'channel'}->{'pubDate'});
      }
      
      foreach my $item (@{$rss->{'items'}}) {
	  my $itemDate = 0;
	  
	  if($item->{'pubDate'}) {
	      $itemDate = dthttp2epoch($item->{'dc'}->{'date'});
	  } elsif($item->{'description'}) {
	      $itemDate = dthttp2epoch($item->{'description'});
	  } else {
	      print "    RSS DATE convert failed\n";
	  }
	  
	  $latest = ($itemDate > $latest)? $itemDate : $latest;
      }
  } elsif($rssversion eq '0.9') {
      print "    RSS 0.9 not supported\n";
  } else {
      print "    Unknown. not supported\n";
  }

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-10-03 (水) 03:14:18