こんにちは、制作の奥田です。
2015年12月2日に事件は起きました。
Google Feed Apiが突然廃止され、Google Feed Apiを使用してアメブロなどのFeedを取得していたサイトで軒並み403アラートを表示する事態に陥りました。
弊社でも幾つかアメブロのFeedを取得しているサイトが存在していたので対応に追われました。
今回はPHPを使った取得方法と、PHPが使えない場合のJSONPを使った取得方法をご紹介いたします。
Table of contents
PHPによるFeedの取得
これはいろいろなサイトで説明されていますが、アメブロのFeedの例をご紹介します。
まず、simplexml_load_file()という関数を使いFeedをオブジェクトとして取得します。
アメブロのFeedにはタイトルが「PR:」から始まる広告が入っているのでそれを除外し、ループで回しリストに代入します。
最後に出力するという流れです。
以下のソースの[アメブロID]の箇所を変更し、rss.phpというファイルで保存します。(※名前は任意です。)
<?php date_default_timezone_set('Asia/Tokyo'); $url = "http://feedblog.ameba.jp/rss/ameblo/[アメブロID]/rss20.xml"; $rss = simplexml_load_file($url); $output = ''; $i = 0; // 取得件数 $max = 5; if($rss){ foreach( $rss->channel->item as $item ) { /** * タイトル * $item->title ; * リンク * $item->link ; * 更新日時のUNIX TIMESTAMP * $timestamp = strtotime( $item->pubDate ) ; * 詳細 * $item->description; */ if(!preg_match('/^PR:/',$item->title )){ if($i < $max){ $timestamp = strtotime( $item->pubDate ); $date = date( 'Y.m.d',$timestamp ); $output .= '<li>'; $output .= '<time datetime="' . $item->pubDate . '">' . $date . '</time>'; $output .= '<a href="'. $item->link .'" target="_blank">' . $item->title . '</a>'; $output .= '</li>'; $i++; } } } } echo '<ul>'. $output . '</ul>';
あとは取得したいページでAjaxで取得するだけです。
取得したい箇所にdiv#feed要素を追記し、Ajaxで取得します。
(jQueryは必須です。)
<div id="feed"></div>
;(function($){ $(function(){ $.get('rss.php',function(data){ $('#feed').html(data); }) }) })(jQuery);
これで表示はできるはずですので、CSSでスタイリングしてあげるだけです。
APIにしてJSONPでのFeedの取得
ただ、PHPが動かないサーバーでの対応やsimplexml_load_file()が使えないサーバーが存在するので上記の方法ではうまくいかない場合があります。
そんな場合はPHPが使えるサーバーでJSONで出力し、それをJSONPで取得します。
※以下のサンプルはPHPが使えるサーバーが他に有る場合に可能です。
以下のファイルをapiとしてPHPが動くサーバーに設置します。
<?php date_default_timezone_set('Asia/Tokyo'); $url = (isset($_GET['url'])) ? $_GET['url'] : NULL; $callback = (isset($_GET['callback'])) ? $_GET['callback'] : 'callback'; $output = array(); $i = 0; if(isset($_GET['url'])){ $max = (preg_match('/^\d$/',$_GET['max'])) ? $_GET['max'] : 5; } if(!empty($url)){ $rss = simplexml_load_file($url); foreach( $rss->channel->item as $item ) { /** * タイトル * $item->title ; * リンク * $item->link ; * 更新日時のUNIX TIMESTAMP * $timestamp = strtotime( $item->pubDate ) ; * 詳細 * $item->description; */ if(!preg_match('/^PR:/',$item->title )){ if($i < $max){ $timestamp = strtotime( $item->pubDate ); $date = date( 'Y.m.d',$timestamp ); $link = (string) $item->link; $pubDate = (string) $item->pubDate; $output[$i] = array( 'title' => $item->title , 'link' => $link, 'pubDate' => $pubDate, 'date' => $date, ); $i++; } } } } header( 'Content-Type: text/javascript; charset=utf-8' ); echo $callback . "(" . json_encode($output). ")";
取得したいサイトで同じく要素を追記し、以下のスクリプトを書くだけです。
<div id="feed"></div>
<script type="text/JavaScript"> ;(function($){ $(function(){ var api = "APIを設置したURL"; var url = "http://feedblog.ameba.jp/rss/ameblo/[アメブロID]/rss20.xml"; var max = 5; var callback = 'callback'; $.ajax({ url: api + '?url=' + url + '&max=' + max + '&callback=' + callback, dataType:"jsonp", success:function(data){ var html = '<ul>'; for(var i in data){ html += '<li><time datetime="' + data[i].pubDate + '">' + data[i].date + '</time><a href="' + data[i].link + '" target="_blank">' + data[i].title + '</a></li>'; } html += '</ul>'; $('#feed').html(html); } }); }); })(jQuery); </script>
後は同じくCSSでスタイリングしてあげるだけです。