Home > Perl > RSS Feedの簡単な加工の仕方

RSS Feedの簡単な加工の仕方

  • 2004-05-13 (木)
  • Perl
  • このエントリーを含むはてなブックマーク

CNET Japan の最新ニュースヘッドラインを自分のBLOGのサイドバーに表示させる といった、RSS(*.rdf)を公開している任意のサイトの情報を自分のページに設置できる、RSS FeedをJavaScriptとしてHTMLに埋め込む方法をご紹介。以前、2回に渡って XML::Simple を使った PERL でのXML処理手法を書きましたが(コレコレ)、今回はその手法を使っての実例紹介です。また、Googleにて "RSS javascript" と検索すると、

 miyagawa氏のBlog Developer's Cookbook
 → RSS feed を JavaScript で HTML に埋め込む
 naoya氏のNDO::Weblog
 →RSS を整形して SSI で表示してみました

等のページにて同様の機能を実現する方法が紹介されていましたが、ここで紹介するのはそれらとはまた違った、「簡単なソースコード」「更新に手間がかからない」といった点を重視した実装方法を述べてみます。

作るもの

呼び出される度に、指定したRSS Feedの最新版を取得して、

<!--
document.write('<a href="リンク先1">最新記事1</a><br>');
document.write('<a href="リンク先2">最新記事2</a><br>');
document.write('<a href="リンク先3">最新記事3</a><br>');
//-->

といったJavaScriptを動的に出力するCGIスクリプト。ここでは名前を

 rss2js.cgi

としておきます。

作成したCGIの使い方

HTMLにて外部のjsファイル(JavaScriptファイル)を呼び出すには、

<script language="javascript" type="text/javascript"
src="/path/to/file.js"></script>

と書くことで出来ますが、この src 部分は静的な *.js ファイルである必要はありません。今回作成する rss2js.cgi は呼び出されると「作るもの」項に書いてあるような Javascriptコード を出力するので、これを

<script language="javascript" type="text/javascript"
src="/path/to/rss2js.cgi"></script>

と書くことで、CGIにて動的に作成した最新記事一覧を任意の静的HTML上で表示させる事ができる、といった仕組みになります。

rss2js.cgiのソースコード

で、このCGIのソースコードですが、記述する処理は大体こんな感じになります:

 (1)RSS Feed を取得して Perl構造体に変換する
 (2)JavaScriptで出力する際に必要な文字エスケープ処理を行う
 (3)JavaScriptの document.write 文として出力する

(1)の部分にて、以前に書いた「XML::Simple の使い方」と「その2」で書いた手法を用いています。取り込むRSSは CNET JapanのHEADLINE NEWS RSS にしてみました。(2)は作ってる途中で気づいた事です。JavaScriptで出力する文字列の中に ' (apostrophi) や 改行文字が含まれていると document.write(' hogehoge ' ) の処理が正しく実行されませんので、PERL側で事前にエスケープさせます。(3)でのポイントはPERLからの出力文字列が JavaScript であることをブラウザに認識させる為に HTTP HEADER を頭で出力している点です。で、実際のソースコードは以下の様になります:

#!/usr/bin/perl

use LWP::Simple;
use XML::Simple;
use Jcode;

### RSS取得&解析 ###
my $url = "http://japan.cnet.com/rss/index.rdf";
my $xml = LWP::Simple::get($url);
my $x   = new XML::Simple;
my $obj = $x->XMLin($xml);
$obj    = &ConvertEncoding($obj,'utf8','euc');

### 文字エスケープ ###
my ($v);
foreach $v (@{$obj->{item}}){
    $v->{title} =~ s/'/\\'/g;
    $v->{title} =~ s/[\r\n]//g;
}

### JavaScript出力 ###
my $v;
print qq(Content-type: text/javascript\n\n);
print qq(<!--\n);
foreach $v (@{$obj->{item}}){
    print qq(document.write\('<a href="$v->{link}" );
    print qq(target="_blank">- $v->{title}</a><BR>'\);\n);
}
print qq(//-->\n);


# _____ Subroutine : 構造体の文字コード置換 _____________________

sub ConvertEncoding($$$){

    my($p,$from,$to) = @_;
    die qq(ConvertEncoding : need to specify character encoding
           you'd want to convert to) if(!$to);
    my $r = ref($p);
    
     ### if [BLESSED] HASH REFERENCE ###
    if($r eq 'HASH' || ( !$r && $p =~ /=HASH\(.+\)/ )){
        my $v;
        foreach $v (keys %{$p}){
            $p->{$v} = &ConvertEncoding($p->{$v},$from,$to);
        }
    }
    
    ### if [BLESSED] ARRAY REFERENCE ###
    elsif($r eq 'ARRAY' || ( !$r && $p =~ /=ARRAY\(.+\)/ )){
        my $i=0;
        for ($i;$i <= $#{$p};$i++){
            $p->[$i] = &ConvertEncoding($p->[$i],$from,$to);
        }
    }
    
    ### if [BLESSED] CODE REFERENCE ###
    elsif($r eq 'CODE' || ( !$r && $p =~ /=CODE\(.+\)/ )){
    }
    
    ### if SCALAR ###
    else{
        $p = Jcode->new($p,$from)->$to;
    }
    return $p;
}

完成

作成した rss2js.cgi をサーバに設置したうえで、任意のHTMLの一覧を表示させたい場所に以下のScriptタグを記述すれば完成です:

<script language="javascript" type="text/javascript"
src="/path/to/rss2js.cgi"></script>

今回は最低限のコードで、最低限の機能のみを実装しましたが、さらに拡張機能として、

 任意のRSSをGETパラメータにて指定できる
 一覧表示件数をGETパラメータにて指定できる
 出力する一覧の文字コードをGETパラメータにて指定できる

等があったら便利ですよね。その辺のカスタマイズもPERL CGIですので容易に実現できるかと思います。今回紹介した方法+上記のカスタマイズを実装させた上で、iandeth. では MyClip の Clip Ranking RSS をサイドメニューの「注目ニュース」として表示させています。bashiの注目するニュースではなくて、他の皆が注目しているニュースを自分のBLOGに表示させてるという横着っぷり /w。

追記

後日Googleで似たような記事/サービスについて調べてみたら... 速攻で幾つか有名っぽいページを見つけてしまいました^^;

 B.B.氏のB.B.'sWebSpace : ページ埋め込み型RSSリーダ jsRSS.cgi
 rss-jp.netの read_rss.cgi

最初にもっと調べてから書けよ俺...。

Comments:0

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Home > Perl > RSS Feedの簡単な加工の仕方

Search
Feeds

Page Top