「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 = "http://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( "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://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( "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://www.lesson5.info/?feed=rss2", "http://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、はてなブログなどブログサービス別に日付対応なども載っていて助かるかと思います。
こんにちは、ソースコードを使ってみたのですが、rss-phpは,fc2ブログやwordperssでは、取得出来ないのでしょうか。
ftpなどを使って、rss-phpをサーバーにアップロードできれば基本的には使用できます。
fc2ブログはftp設定があるようなので、以下の方法でアップロードできます。
http://help.fc2.com/blog/manual/group110/1457
ただ、セキュリティ的にfc2ブログでphpを動かせることが可能かまでは確認していません。
wordpressをご使用であれば通常ftpでwordpress自体もアップロードされていると思いますので、rss-phpの設置もOKだと思います。
返信ありがとうございます。
すいません質問の仕方間違ってました。
fcブログとwordpressのRSSを使うとエラーがでるので
エラーがでないようにする方法があるのかと思ってお聞きしました。
他のブログを見てると、個別にsimple_load_fileを使うしかないみたいのですが
一応見たサイトです。
http://kana-lier.com/web/php_rssfeed/
僕もどっちのことか迷ってましたが逆でしたね、すいません…
僕の環境で試したところ、fc2ブログのrssはrss1.0のため取得できないのではないかと思います。
念のため同じ1.0でrss出力されているライブドアブログも試してみましたが取得できませんでした。
http://qiita.com/hitonari45/items/c42fb79e16122eedae16
上記のページのように「rss-php」がおかしいというわけでなく、
rss取得後、日付などの取得でこけているんじゃないかなと考えて、
日付なんかを外して処理してみましたがサイト名やurlも出力されてなかったので、「rss-php」自体こけてそうです。
rss1.0なんかを扱うときはシンプルにsimple_load_fileを使うのがいいかもしれません。
解決できずすいません…
いえいえ、丁寧にすぐ返信してくださってありがとうございます。
もやもやが解決出来て simple_loadを使おうかと思います。
どうもです。
はじめまして。いつもサイトを拝見し、勉強させていただいております。ありがとうございます。
上記のコードで質問です。
「対象RSSが複数の場合でPHPで書き出す」で、『RSSごとに1エントリづつ抽出』するケースがありますが、
ここを『RSSごとに5エントリづつ抽出』場合は、コードをどのように書き換えればよいのでしょうか?
現在、対象RSSが3フィードあり、各5エントリずつ抽出したいと思っております。
お忙しいところ恐縮ですが、教授いただけないでしょうか。
よろしくお願いいたします。
39行目あたりにある
for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { なんかに変更すればいいかと思います〜
こんにちわ。
ソースコード助かりました。
【したいこと】複数のブログ(アメーバ―オウンド)のRSSを表示させたい
どうしてもURLの指定でつまずいています。
URLを入れるとエラーになってしまうのですが、どこにどのようなURLをいれたらいいでしょうか。
※アメーバ―オウンドのrss「~/rss20.xml」というURLをいれました。
// 取得するフィードのURLを指定
$urls = array(
“http://www.lesson5.info/?feed=rss2”,
“http://www.lesson5.info/?feed=rss2”,
“http://www.lesson5.info/?feed=rss2”,
“http://www.lesson5.info/?feed=rss2”,
“http://www.lesson5.info/?feed=rss2”,
“http://www.lesson5.info/?feed=rss2”
);
よろしくお願いします!
$urls = array(
“~/rss20.xml”,
“~/rss20.xml”,
“~/rss20.xml”
);
これで大丈夫なはずですがアメーバオウンドは試したことないので何か原因が他にあるかもしれません
複数RSSから取得する方法を探していて、大変参考になりました。
ひとつ質問なのですが、複数ブログの場合に各1エントリずつではなく、抽出数を増やすにはどうしたらよいのでしょうか。
39行目あたりにある
for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { なんかに変更すればいいかと思います〜
はじめまして。
「対象RSSが複数の場合でPHPで書き出す」の場合で
各rssの取得エントリー数を変えるにはどうすればよいのでしょうか。
いろいろいじったりしてみたのですが、phpの知識がなくうまくいかず…。
恐れ入りますが、ご教示いただければ幸いです。
他の方も同じ質問あったので参考にされてみてください!
お世話になります。
googleのfeedが終了して困っています。
PHP初心者ですみません。
詳しく教えて頂けましたら大変ありがたいです。
このページの上部から順に
dg/rss-php · GitHub←こちらから ①example-rss.php←これをクリックしコピーし、
目的のHTMLと同じ階層に単体のPHPファイル作成しペーストしてサーバーにupしました。
同じ階層にPHPファイルとしておいておけばいいんですよね?
次に
②「対象RSSが1つの場合
表示したいrssが1つの場合はこちら。
こちらはキャッシュを指定していません。
<?php
// ライブラリの読み込み
require_once…………. 」 ←こちらのPHPスクリプトはどちらにペーストするのでしょうか。
また①と②のスクリプトに対して必須入力項目とその内容の例えを教えていただけますでしょうか?
どれを何処に張って、どこどこはこのように入力しましょうという様な具合でおしえていただけますでしょうか、お願い致します。
また
最後には目的のHTMLの新着欄に<div id="feed"></div>←この様な事は必要なのでしょうか?
情報の取得方法も教えて下さいませ。
設置予定feed urlはジュゲムブログで以下の物がございます。
http://◯◯◯.jugem.jp/?mode=rss
各エントリーから5件抽出する場合に、
for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { とありますが、
5にしてみた所、各エントリー最新5件を除いた6件目を一つずつ表示してしまいます。
他に修正すべき箇所ありますでしょうか。ご教示いただければ幸いでございます。
私も同じ表示です。
他に方ありますでしょうか?
RSS2.0では上記対象RSSが1つの場合のサンプルコードで取得できましたが、RSS1.0の場合には取得できず空欄のままでした
例えば → http://xn--1sq130aw9j5qh.com/index.rdf (価格激安PC家電最新情報ブログさんのところ)
ご報告まで。
RSS1.0はこのrss-phpでは対応してないようです
はじめまして。自分で試してみてみたのですが、
うまくいかなかったので教えていただきたいです。
「対象RSSが1つの場合」の最大件数の変更を行いたい場合どうしたらいいですか?
よろしくお願いいたします
20行目のforeachを下記のサイトのように指定回数で抜けてあげればよいと思います。
http://www.geekzshu.com/php/509
はじめまして。
知識のない自分にも理解しやすく非常に助かっております。
一点質問なのですが、最後のJavascriptのJson処理について、いろいろ試しているのですが、うまくHTMLとして表示できません。
できればscriptのコピペで色んなページの#id部分に表示させたいのですが、例文など教えていただけると助かります。
勉強不足で申し訳ありませんがよろしくお願いいたします。