F1最新ニュースという、複数のサイトのトピックを配信する、まとめサイトをWordPressで作ることになりました。
その為に、複数のRSSフィードから一つのRSSフィードを生成する必要が生じたので、調べたことをメモしておきます。
ただ単に、RSSを読み込んで記事として配信するだけならば、FeedWordpress というプラグインがあるので、非常に作成が簡単なんです。
【参考】
FeedWordPressの設定
しかし、引用サイト毎に表記の揺れがあるのが気になって、わざわざRSSを改めて生成するという方法を採ることにしました。「続きを読む」が、サイトによっては「more」になっていたり、テキスト形式で配信するものもあれば、HTMLタグが入って配信するものがあったりなどです。
PHPのコードを参考にしたのは以下のサイトです。というよりも、2つのサイトに書いてあるコードを丸パクリしたと言っても過言ではありません。
【参考】
複数のRSSフィードを高速でまとめる方法
RSS 2.0 形式のフィードを作成するライブラリ
これらのサイトを参考にして出来上がったのが、以下のコードです。現在、RSSを生成するのに使っているコードと全く一緒のものとなります。
<?php set_time_limit(0); //表示記事数 $hyojiNum = 50; //フィード登録 $data['feedurl'][] = 'http://hoge.jp/rss/index.rdf'; $data['feedurl'][] = 'http://hogehoge.jp/rss/feeds/'; //$data['feedurl'][] = ''; いくらでも追加してください $rssList = $data['feedurl']; //キャッシュ準備 require_once('Cache/Lite.php'); $cacheDir = 'rsscache/'; $lifeTime = 60*60; $automaticCleaningFactor = 100; $options = array('cacheDir' => $cacheDir ,'caching' => true, 'lifeTime' => $lifeTime, 'automaticSerialization' => 'true','automaticCleaningFactor' => $automaticCleaningFactor); $cacheData = new Cache_Lite($options); $outdata = $cacheData->get('rsscache'); if(!$outdata) { //同時呼び出し $rssdataRaw = multiRequest($rssList); for($n=0;$n<count($rssdataRaw);$n++){ //URL設定 $rssdata = simplexml_load_string($rssdataRaw[$n]); if($rssdata->channel->item) $rssdata = $rssdata->channel; if($rssdata->item){ foreach($rssdata->item as $myEntry){ $rssDate = $myEntry->pubDate; if(!$rssDate) $rssDate = $myEntry->children("http://purl.org/dc/elements/1.1/")->date; date_default_timezone_set('Asia/Tokyo'); $myDateGNU = strtotime($rssDate); $myDate = date('Y/m/d',$myDateGNU); $myTitle = $myEntry->title; //タイトル取得 $myLink = $myEntry->link; //リンクURL取得 $myDescription = $myEntry->description; //出力内容(CSSOK) ///////////////////// //表示しない記事 if(preg_match('/PR:/',$myTitle)){continue;} if(preg_match('@as-web.jp/news/info.php@s',$myLink)){continue;} //ディスクリプションの整形 $patterns = array(); $patterns[0] = '/<a href=".*?">続きを読む<\/a>/'; $patterns[1] = '/<.*?>/'; $replacements = array(); $replacements[0] = ''; $replacements[1] = ''; $myDescription = preg_replace($patterns, $replacements, $myDescription); $myDescription = html_paragraph($myDescription); $patterns = array(); $patterns[0] = '/<\/p>$/s'; $patterns[1] = '/ \[&#8230;\]/'; $replacements = array(); $replacements[0] = " (<a rel=\"nofollow\" href=\"{$myLink}\">引用元</a>)</p>"; $replacements[1] = '...'; $myDescription = preg_replace($patterns, $replacements, $myDescription); $outdata[$myDateGNU] = "$myDateGNU<+>$myLink<+>$myTitle<+>$myDescription"; } } } //ソート krsort($outdata); $cacheData->save($outdata,'rsscache'); } $nn = 0; $html = ''; include_once 'rss2/RssFeed.php'; include_once 'rss2/RssItem.php'; $rss = new RssFeed(); $rss->title('F1の最新情報'); $rss->description('F1の最新情報'); $rss->link('http://f1-news.info/'); $rss->atomLink('http://f1-news.info/'); foreach($outdata as $outdata) { $nn++; $outdatas = explode("<+>", $outdata); //"$myDateGNU<+>$myLink<+>$myTitle<+>$myDescription"; $myDate = date('Y-m-d H:i:s',$outdatas[0]); $item = new RssItem(); $item->title($outdatas[2]); $item->description($outdatas[3]); $item->link($outdatas[1]); $item->guid($outdatas[1]); $item->pubDate($myDate); $rss->addItem($item); if($nn == $hyojiNum) break; } //$html = '<html lang="ja" style="overflow-x:hidden;"><head><META http-equiv="Content-Type" content="text/html; charset=utf-8"></head><div>'.$html.'</div></html>'; header('Content-type:application/rss+xml'); echo $rss->saveXML(); //同時呼び出し関数 function multiRequest($data, $options = array()) { // array of curl handles $curly = array(); // data to be returned $result = array(); // multi handle $mh = curl_multi_init(); // loop through $data and create curl handles // then add them to the multi-handle foreach ($data as $id => $d) { $curly[$id] = curl_init(); $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d; curl_setopt($curly[$id], CURLOPT_URL, $url); curl_setopt($curly[$id], CURLOPT_HEADER, 0); curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1); // post? if (is_array($d)) { if (!empty($d['post'])) { curl_setopt($curly[$id], CURLOPT_POST, 1); curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']); } } // extra options? if (!empty($options)) { curl_setopt_array($curly[$id], $options); } curl_multi_add_handle($mh, $curly[$id]); } // execute the handles $running = null; do { curl_multi_exec($mh, $running); } while($running > 0); // get content and remove handles foreach($curly as $id => $c) { $result[$id] = curl_multi_getcontent($c); curl_multi_remove_handle($mh, $c); } // all done curl_multi_close($mh); return $result; } function html_paragraph($str, $xhtml=true){ $arr = preg_split("/\R\R+/", $str, -1, PREG_SPLIT_NO_EMPTY); $result = ""; foreach($arr as $value){ $value = htmlspecialchars($value, ENT_QUOTES); $result .= '<p>' . nl2br($value, $xhtml) . "</p>\n"; } return $result; } ?>
以上、参考にして下さい。