「Google Feed API」の代替として「rss-php」でRSSやAtomフィードを取得・表示する
Google Feed APIが以前から非推奨になってからしばらく立ちますが、いよいよ今日、2015年12月2日、Googleらしくすっぱりと動かなくなりました。
2015年12月4日 いったんAPIが復帰しているみたい。暫定的な処置なのかもで構わずphpやjsonに移行しておいたほうがいいと思います。
まずほとんどのweb制作者の方たちが対応に追われているんじゃないでしょうか…
抱えてる案件が一段落している時だったので僕は直撃を避けれた感じではありますが、今日、タイトなスケジュールをこなしていた方にはGoogleが嫌いになる人もいるかもしれませんね。
twitterなんかでもどのように対応するか色々大変な声が上がってたみたいですが、
僕は簡単に早く対応したかったので、あっさりPHPで代替しました。
jsだとクロスドメインまわりで面倒くさいですが、phpだとそれがないのでほんとに簡単に終わりました。
元からこれにしとけばよかった…
使用ライブラリ
今回使わせてもらったphpのライブラリ「rss-php」はこちらです。
dg/rss-php · GitHub
基本的にこのライブラリは、rssをロードしたりパースしたりを簡単にしてくれるもの。
特にキャッシュの指定ができるのがいいですね。
使い方によっては10以上のrssをまとめて取ってきて処理することもあるでしょうし、それをアクセス都度こなすのは遅くなるしキャッシュできるのはありがたい。
設置
ライブラリである「Feed.php」自体は任意の場所に置きましょう。
そのライブラリを表示用のphpからinclude,requireします。
それではケースに分けてコード置いておきます。
対象RSSが1つの場合
対象RSSが複数の場合でPHPで書き出す
対象RSSが複数の場合でPHPでJSONを返しjavascriptで表示
対象RSSが1つの場合
表示したいrssが1つの場合はこちら。
こちらはキャッシュを指定していません。
<?php // ライブラリの読み込み require_once ($_SERVER['DOCUMENT_ROOT'] . '/lib/Feed.php'); // 取得するフィードのURLを指定 $url = "https://www.lesson5.info/?feed=rss2" ; // インスタンスの作成 $feed = new Feed ; // RSSを読み込む $rss = $feed->loadRss( $url ) ; // HTML表示用 $html = '' ; $sitename = $rss->title ; foreach( $rss->item as $item ) { // 各エントリーの処理 $title = $item->title ; // タイトル $link = $item->link ; // リンク // 日付の取得(UNIX TIMESTAMP) foreach( array( "pubDate" , "date_timestamp" , "dc:date" , "published" , "issued" ) as $time ) { if( isset( $item->{ $time } ) && !empty( $item->{ $time } ) ) { $timestamp = ( is_int( $item->{ $time } ) ) ? $item->{ $time } : strtotime( $item->{ $time } ) ; break ; } } // 仮に日付が取得できなかったら現在時刻 if( !isset( $timestamp ) ) { $timestamp = time() ; } // 表示 $html .= '<dt><a href="' . $link . '" target="_blank">' . $title . '</a> (' . date( "Y/m/d" , $timestamp ) . ')</dt><dd>' . $sitename . '</dd>' ; } ?> <dl> <?php echo $html ?> </dl>
対象RSSが複数の場合でPHPで書き出す
こちらはキャッシュを指定しています。
6つのブログから各最新1件のエントリ(全部で5件まで)を表示するようにしています。
※xmlの形式はすべてのブログで同一前提です。日付などフォーマットが違うケースもあるのでその辺りは追加で対応が必要です。
<?php // ライブラリの読み込み require_once ($_SERVER['DOCUMENT_ROOT'] . '/lib/Feed.php'); // キャッシュの設定 Feed::$cacheDir = $_SERVER['DOCUMENT_ROOT'] . '/temp'; Feed::$cacheExpire = '1 hours'; // HTML表示用 $html = '' ; // 表示最大件数 $maxview = 5 ; // 取得するフィードのURLを指定 $urls = array( "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2" ); // 各rssをまとめた配列 $entrylist = array(); // RSSごとに1エントリづつ抽出 for ($i = 0; $i < count($urls); $i++) { $url = $urls[$i]; // インスタンスの作成 $feed = new Feed ; // RSSを読み込む $rss = Feed::loadRss($url); for ($entry = 0; $entry < 1; $entry++) { $sitename = $rss->title ; $sitelink = $rss->link ; $item = $rss->item[$entry]; // 各エントリーの処理 $title = $item->title ; $link = $item->link ; $timestamp = strtotime( $item->pubDate ) ; // 配列に $entrylist[$i]['sitename'] = $sitename; $entrylist[$i]['sitelink'] = $sitelink; $entrylist[$i]['title'] = $title; $entrylist[$i]['link'] = $link; $entrylist[$i]['timestamp'] = $timestamp; } } // 日付でソート foreach ((array)$entrylist as $key => $value) { $sort[$key] = $value['timestamp']; } array_multisort($sort, SORT_DESC, $entrylist); // 書き出す件数を設定 if ( count($entrylist) > $maxview ) { $entrynum = $maxview; } else { $entrynum = count($entrylist); } // 書き出し for ($i = 0; $i < $entrynum; $i++) { $html .= '<dt><a href="' . $entrylist[$i]['link'] . '" target="_blank">' . $entrylist[$i]['title'] . '</a> (' . date( "Y/m/d" , $entrylist[$i]['timestamp'] ) . ')</dt><dd><a href="' . $entrylist[$i]['sitelink'] . '" target="_blank">' . $entrylist[$i]['sitename'] . '</a></dd>' ; } ?> <dl> <?php echo $html ?> </dl>
めんどくさいめんどくさいと思いながら、今までは全部Googleさん任せでした。
jsの制限を抜けれるのであればphpで対応したほうがやっぱ早いですね…
まぁ、jsでっていうのが前提で「Google Feed API」を使ってたので当然ですが…
対象RSSが複数の場合でPHPでJSONを返しjavascriptで表示
どうしても以前のGoogle Feed APIみたくjavascriptを使用したいならこちら。
ひとつ前の「対象RSSが複数の場合でPHPで書き出す」ケースではphpで表示していましたが、
php自体はJSONを返すようにして、javascript側でJSONを受け取り整形表示したい時に。
PHP
<?php // ライブラリの読み込み require_once ($_SERVER['DOCUMENT_ROOT'] . '/lib/Feed.php'); // キャッシュの設定 Feed::$cacheDir = $_SERVER['DOCUMENT_ROOT'] . '/temp'; Feed::$cacheExpire = '1 hours'; // HTML表示用 $html = '' ; // 取得するフィードのURLを指定 $urls = array( "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2", "https://www.lesson5.info/?feed=rss2" ); // 各rssをまとめた配列 $entrylist = array(); // RSSごとに1エントリづつ抽出 for ($i = 0; $i < count($urls); $i++) { $url = $urls[$i]; // インスタンスの作成 $feed = new Feed ; // RSSを読み込む $rss = Feed::loadRss($url); for ($entry = 0; $entry < 1; $entry++) { $sitename = $rss->title ; $sitelink = $rss->link ; $item = $rss->item[$entry]; // 各エントリーの処理 $title = $item->title ; $link = $item->link ; $timestamp = strtotime( $item->pubDate ) ; // 配列に $entrylist[$i]['sitename'] = $sitename; $entrylist[$i]['sitelink'] = $sitelink; $entrylist[$i]['title'] = $title; $entrylist[$i]['link'] = $link; $entrylist[$i]['timestamp'] = $timestamp; } } // 日付でソート foreach ((array)$entrylist as $key => $value) { $sort[$key] = $value['timestamp']; } array_multisort($sort, SORT_DESC, $entrylist); // JSONを返す echo json_encode($entrylist); exit; ?>
JS
<script> $(function() { $.ajax({ type: 'GET', url: 'getjson.php', //先ほどのphpへのパス success: function(res) { // ここに取得したjsonの処理など } }); }); </script>
こうすればPHPさえサーバーのどこかに置ければクロスドメイン関係なくjsでも取得・表示できるのではないでしょうか。
今回参考にさせてもらったブログはこちらです。
PHPでRSSやAtomのフィードを取得する方法
Ameblo、Jugem、FC2、Livedoor、WordPress、はてなブログなどブログサービス別に日付対応なども載っていて助かるかと思います。
22 thoughts on “「Google Feed API」の代替として「rss-php」でRSSやAtomフィードを取得・表示する”