10 May 2009

(PHP) XML_Feed_ParserによるRSSファイルの読み込み

RSSデータファイル(Atom, RSS)をHTTPサーバより取得し、Pear XML_Feed_Parserクラスを用いて要素分解(連想配列に読み込み)を行う手法

次の例では、Atom, RSS0.91, RSS1, RSS2.0が読み込み可能である。


function read_rss($uri)
{
$nSwTopicCount = 10; // 表示する記事数
$nSwDescription = 1; // 本文を表示するかどうか
$nSwPrevDays = 1; // 過去1日分を表示

// RSSファイルの受信
$strRssSource = file_get_contents($uri);
if($strRssSource == false)
{
print("<p>RSSファイル読み込み失敗</p>\n");
return ;
}

// XML_RSSクラスの初期化と、受信
$rss =& new XML_Feed_Parser($strRssSource);

printf("<div style=\"background-color:#d5d9e6; padding-top:3px;\"><p><span style=\"font-size:12pt;\">%s</span> (%s) <a target=\"_blank\" href=\"%s\">%s</a></p></div>\n", trim($rss->title),
$rss->__get('version'), $uri, $uri);

$i = 0;
print("<table>\n".
"\t<tr><td width=\"120px\"></td><td></td></tr>\n");
foreach ($rss as $item) { // データの取り出し
$strTitle = $item->title;
$strLink = $item->link;
$strDescription = $item->description;
$strContent = $item->content;

// RSSのバージョンにより、日付の変数名が違うことによる処理
$strDate = $item->date; // RSS 1, 1.1
if($strDate==null) $strDate = $item->published; // atom
if($strDate==null) $strDate = $item->pubDate; // RSS 2
if($strDate==null) $strDate = $item->updated; // RSS 1, atom
$arrDate = getdate($strDate);

if($strDate!=null && time()-$strDate>$nSwPrevDays*24*3600+1)
continue; // 指定期間より古い

printf("\t<tr><td>%04d/%02d/%02d %02d:%02d</td><td><a target=\"_blank\" style=\"font-size:12pt;\" href=\"%s\">%s</a></td></tr>\n",
$arrDate['year'], $arrDate['mon'], $arrDate['mday'], $arrDate['hours'], $arrDate['minutes'],
htmlspecialchars($strLink), htmlspecialchars($strTitle));

if($nSwDescription == 1)
{
if(!empty($strDescription))
printf("<tr><td></td><td>%s</td></tr>\n", htmlspecialchars(strip_tags($strDescription)));
else
printf("<tr><td></td><td>%s</td></tr>\n", htmlspecialchars(strip_tags($strContent)));
}

$i++;
if($i>=$nSwTopicCount) break; // 指定されたトピック数のみ表示
}

print("</table>\n");
return ;
}

なお、Pearにh、XML_RSSというクラスもあるが、こちらはRSS0.91,RSS1, RSS2.0の読み込みは可能だが、Atomの読み込みはサポートしていない。 このクラスの読み込みテストを行ったときの検証コードは次のようなもの。


$rss =& new XML_RSS($uri);
$rss->parse();
print("配列の要素数 = ". count($rss->getItems())."\n");
foreach ($rss->getItems() as $item) { // データの取り出し
print_r($item);
}

今回読み込みの確認を行っているのは…

*Reuters: トップニュース (RSS 2.0) http://feeds.reuters.com/reuters/JPTopNews
*政治 - アサヒ・コム (RSS 1.0) http://rss.asahi.com/f/asahi_politics
*YOMIURI ONLINE(読売新聞)主要ニュース (RSS 2.0) http://rss.yomiuri.co.jp/f/yol_topstories
*毎日jp-ニュース速報(総合) (RSS 1.0) http://mainichi.pheedo.jp/f/mainichijp_flash
*Yahoo!ニュース - 国内 - J-CASTニュース (RSS 2.0) http://headlines.yahoo.co.jp/rss/jct_dom.xml
*nikkei BPnet 最新記事一覧 (RSS 1.0) http://feed.nikkeibp.co.jp/rss/nikkeibp/index.rdf
*ITpro総合 (RSS 1.0) http://itpro.nikkeibp.co.jp/rss/ITpro.rdf
*ITmedia News 国内記事 最新記事一覧 (RSS 2.0) http://rss.rssad.jp/rss/itmnews/2.0/news_domestic.xml
*Enterprise Watch (RSS 1.0) http://www.pheedo.jp/f/enterprise_watch/
*SourceForge.JP Magazine (RSS 1.0) http://www.pheedo.jp/f/sourceforgejp/magazine
*WIRED VISION (Atom 1.0) http://rss.rssad.jp/rss/wiredvision/feed/atom.xml
*スラッシュドット・ジャパン (RSS 1.0) http://www.pheedo.jp/f/slashdot_japan
*ダイヤモンド・オンライン - 新着トピックス (RSS 2.0) http://diamond.jp/feed.xml
*東洋経済オンライン(ビジネス) (RSS 1.0) http://feeds.feedburner.jp/business_all
*帝国データバンク 大型倒産速報 (RSS 1.0) http://www.tdb.co.jp/rss/jouhou.rdf

これくらい確認を取っておけば、大体OKそうなんだけどね。