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そうなんだけどね。