「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、はてなブログなどブログサービス別に日付対応なども載っていて助かるかと思います。

20 thoughts on “「Google Feed API」の代替として「rss-php」でRSSやAtomフィードを取得・表示する”

  1. コンヤガヤマダ says:

    こんにちは、ソースコードを使ってみたのですが、rss-phpは,fc2ブログやwordperssでは、取得出来ないのでしょうか。

    1. ひさっち says:

      ftpなどを使って、rss-phpをサーバーにアップロードできれば基本的には使用できます。

      fc2ブログはftp設定があるようなので、以下の方法でアップロードできます。
      http://help.fc2.com/blog/manual/group110/1457
      ただ、セキュリティ的にfc2ブログでphpを動かせることが可能かまでは確認していません。

      wordpressをご使用であれば通常ftpでwordpress自体もアップロードされていると思いますので、rss-phpの設置もOKだと思います。

  2. コンヤガヤマダ says:

    返信ありがとうございます。
    すいません質問の仕方間違ってました。
    fcブログとwordpressのRSSを使うとエラーがでるので
    エラーがでないようにする方法があるのかと思ってお聞きしました。

    他のブログを見てると、個別にsimple_load_fileを使うしかないみたいのですが
    一応見たサイトです。
    http://kana-lier.com/web/php_rssfeed/

    1. ひさっち says:

      僕もどっちのことか迷ってましたが逆でしたね、すいません…

      僕の環境で試したところ、fc2ブログのrssはrss1.0のため取得できないのではないかと思います。
      念のため同じ1.0でrss出力されているライブドアブログも試してみましたが取得できませんでした。

      http://qiita.com/hitonari45/items/c42fb79e16122eedae16

      上記のページのように「rss-php」がおかしいというわけでなく、
      rss取得後、日付などの取得でこけているんじゃないかなと考えて、
      日付なんかを外して処理してみましたがサイト名やurlも出力されてなかったので、「rss-php」自体こけてそうです。

      rss1.0なんかを扱うときはシンプルにsimple_load_fileを使うのがいいかもしれません。

      解決できずすいません…

  3. コンヤガヤマダ says:

    いえいえ、丁寧にすぐ返信してくださってありがとうございます。
    もやもやが解決出来て simple_loadを使おうかと思います。
    どうもです。

  4. ライラックミモザ says:

    はじめまして。いつもサイトを拝見し、勉強させていただいております。ありがとうございます。
    上記のコードで質問です。
    「対象RSSが複数の場合でPHPで書き出す」で、『RSSごとに1エントリづつ抽出』するケースがありますが、
    ここを『RSSごとに5エントリづつ抽出』場合は、コードをどのように書き換えればよいのでしょうか?
    現在、対象RSSが3フィードあり、各5エントリずつ抽出したいと思っております。
    お忙しいところ恐縮ですが、教授いただけないでしょうか。
    よろしくお願いいたします。

    1. ひさっち says:

      39行目あたりにある

      for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { なんかに変更すればいいかと思います〜

  5. ちり紙 says:

    こんにちわ。
    ソースコード助かりました。

    【したいこと】複数のブログ(アメーバ―オウンド)の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”
    );

    よろしくお願いします!

    1. ひさっち says:

      $urls = array(
      “~/rss20.xml”,
      “~/rss20.xml”,
      “~/rss20.xml”
      );

      これで大丈夫なはずですがアメーバオウンドは試したことないので何か原因が他にあるかもしれません

  6. 匿名 says:

    複数RSSから取得する方法を探していて、大変参考になりました。
    ひとつ質問なのですが、複数ブログの場合に各1エントリずつではなく、抽出数を増やすにはどうしたらよいのでしょうか。

    1. ひさっち says:

      39行目あたりにある

      for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { なんかに変更すればいいかと思います〜

  7. Pingback: Google Feed API が廃止になったので件数を指定したリスト表示を代替え案での覚え書き | Yomogi★Log
  8. Trackback: Google Feed API が廃止になったので件数を指定したリスト表示を代替え案での覚え書き | Yomogi★Log
  9. sangou says:

    はじめまして。
    「対象RSSが複数の場合でPHPで書き出す」の場合で
    各rssの取得エントリー数を変えるにはどうすればよいのでしょうか。
    いろいろいじったりしてみたのですが、phpの知識がなくうまくいかず…。
    恐れ入りますが、ご教示いただければ幸いです。

    1. ひさっち says:

      他の方も同じ質問あったので参考にされてみてください!

  10. to says:

    お世話になります。
    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

  11. masa says:

    各エントリーから5件抽出する場合に、
    for ($entry = 0; $entry < 1; $entry++) { を for ($entry = 0; $entry < 5; $entry++) { とありますが、
    5にしてみた所、各エントリー最新5件を除いた6件目を一つずつ表示してしまいます。
    他に修正すべき箇所ありますでしょうか。ご教示いただければ幸いでございます。

  12. PHP beginner says:

    RSS2.0では上記対象RSSが1つの場合のサンプルコードで取得できましたが、RSS1.0の場合には取得できず空欄のままでした
    例えば → http://xn--1sq130aw9j5qh.com/index.rdf (価格激安PC家電最新情報ブログさんのところ)
    ご報告まで。

    1. ひさっち says:

      RSS1.0はこのrss-phpでは対応してないようです

  13. サカノモト says:

    はじめまして。自分で試してみてみたのですが、
    うまくいかなかったので教えていただきたいです。

    「対象RSSが1つの場合」の最大件数の変更を行いたい場合どうしたらいいですか?

    よろしくお願いいたします

    1. ひさっち says:

      20行目のforeachを下記のサイトのように指定回数で抜けてあげればよいと思います。
      http://www.geekzshu.com/php/509

コメントを残す

メールアドレスが公開されることはありません。