高見知英のかいはつにっし(β)

高見知英のアプリケーション開発日誌 のほか、地域活動などの活動報告ブログ。

磯子マガジンのRSS生成スクリプト

今後お世話になることも多いですし、磯子マガジンさんのRSSを生成するスクリプトを作ってみました

#!/usr/bin/perl
use lib q/lib/;
use LWP::UserAgent;
use Encode;
use IO::File;
use XML::RSS;
my $DOMAIN = 'isomaga.com';
my $URL_MAIN = "http://$DOMAIN/";
my $CACHEFILE = 'isomaga.cache';
$ua = new LWP::UserAgent;
if ($ENV{GATEWAY_INTERFACE}) {
  require KCatch;
}

if(!(-e $CACHEFILE) || ([stat($CACHEFILE)]->[9] + 60) < scalar time)
{
  my $request = HTTP::Request->new(GET => $URL_MAIN);
  my $res = $ua->request($request);
  my $html = $res->content;
  my $file = new IO::File($CACHEFILE, 'w') || die "can't write cache! ($!)";
  $file->write($html);
  undef $file;
}

{
  my $rss = new XML::RSS(encode_output => 0);
  $rss->channel(
    title => Encode::decode('UTF-8', '磯子マガジン RSS'),
    link => $URL_MAIN,
    description => Encode::decode('UTF-8', '磯子マガジン トップ記事一覧'),
    language => 'ja');
  my $file = new IO::File($CACHEFILE, 'r') || die "can't read cache! ($!)";
  my $html = decode('Shift_JIS', join('', $file->getlines));
  while($html =~ m{<TD>.*?<A href="([\w/\.]*)" class="middle_title">([^<]*?)</A>.*?<BR>(.*?)</TD>}sg)
  {
    # よくわからない。冗長に書かないとうまく動かない
    my %data = (
      url => $1,
      title => $2,
      summary => $3);
    $data{summary} =~ s/^\s+//mg;
    $data{summary} =~ s/^(<BR>)?$//mg;
    $data{summary} =~ s/(<IMG.*?src="?)([^"]*)/$1$URL_MAIN$2/g;
    if($data{url} ne 'isomaga/welcome.htm')
    {
      $rss->add_item(
        link => $URL_MAIN . $data{url},
        title => $data{title},
        description => "<![CDATA[$data{summary}]]>");
    }
  }

  if ($ENV{GATEWAY_INTERFACE}) {
    require CGI;
    print CGI::header('text/xml; charset=utf-8');
  }
  print Encode::encode('utf-8', $rss->as_string());
}

これで磯子マガジンのトップページに表示されているトピックを一覧できるRSSを生成します。
基本的にほかのサイトのコピーだけ。ただ、概要部分にタグが入っていることがあるので、ちゃんとCDATAにしてあげないといけないことと、記事内に画像が入っていた場合、相対パスになっているので、ベースのURLを書き足す必要があることくらいが注意点でしょうか。
最後の行のEncode::encodeは、「Wide character in print at ...」という警告の対策。字面を見た限り「で?」という感じなのですが、警告に敏感な(ロリポップなど?)サーバで使う可能性も考えて、出ないようにしました。

なお、XML::RSSと、それに必要なDateTime系モジュールは、参考サイトの下二つよりダウンロードしたものをlibディレクトリを作って配置してます。

*1:なぜか日本語圏内には情報が全くなかったので、cpanから直接コピー