こんにちは、制作の奥田です。
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でスタイリングしてあげるだけです。