ぱんぶろ

パンジーの「いいね!」ブログ

[Androidアプリ開発]2chまとめアプリ作成への道②~2chサイトのRSSフィードをまとめたPHPを作る~

      2016/03/30  

2chmatome

前回は、ITproのソースをもとに、RSSリーダーアプリを作成しました。
(⇒ITproのRSSリーダーを真似る

このアプリではITproのRSSフィードを読みこんで表示させているので、
ITproの情報しか出てきません。

2chまとめアプリを作るなら、2chまとめのRSSフィードを流してやる必要があります。

しかも、目指すのは一つの2chまとめサイトのRSSフィードではなく、
複数の2chまとめサイトのRSSフィードを一つにして時系列的に流してあげないといけません。

そこで今回は、バラバラな2chまとめサイトのRSSフィードを一つにまとめるPHPプログラムを作成していきます。

スポンサード リンク

最初に一言

複数のRSSフィードをまとめるPHPプログラムを作る場合は、
インターネット上に公開するために、サーバが必要になります。

そのためレンタルサーバを使う(有料)と、
ドメインを取得(有料)する必要があります。

そういったことがイヤだという方は、
自作じゃなくても複数のRSSフィードをまとめる方法がありますので、
今回の記事は飛ばして次に進んでください!
ITproのアプリにRSSフィードを流す-自作せずにRss Mixを使う

一応メリットとデメリットを挙げておくと、
【メリット】
・手軽。
・無料。

【デメリット】
・急にサービスが終了する可能性がある。
・カスタマイズできない。

といったことが言えます。

2chまとめサイトのRSSフィードをまとめたPHPを作る。

このプログラムを作成する上でチョー参考にさせてもらったのが、
かんきちさん(@kankichi)の⇒複数のRSSフィードを高速でまとめる方法の記事です。

コメントが丁寧に書かれているので、
じっくりと時間をかけてソースを見れば理解できると思います。

このプログラムをそのまま実行すると、下のような画面がブラウザに表示されます。
2chmatome12

これはHTML形式での表示になります。
76~78行目を見てもらうと分かりますが、htmlタグ書かれたものがechoで出力されています。

HTML形式ではなく、XML形式で出力する。

RSSフィードはXML形式で書かれています。
前回作成したITproのRSSリーダーもXMLファイルを解析して表示させているものです。

なので、上のソースをHTML形式ではなく、XML形式で出力してあげる必要があります。
そのために理解しておく必要があるのが、RSSフィードの「型」です。
例えば、ぱんぶろのRSSフィードですが一定の規則に則って書かれていることが分かります。
ぱんぶろのRSSフィード

RSSフィードの型を意識して、XMLファイルを作っていきます。

先にソース公開します。

言葉で説明するよりは、実際にソースを見てもらった方が早いでしょう。

<?php

//XML上部分作成
$rssHeader = <<<RSS
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>サイトタイトル</title>
<description>サイト概要</description>
<link>サイトURL</link>
<author>管理人</author>
<pubDate>日付</pubDate>
<language>ja</language>
RSS;

//フィード登録(例:サッカー関連2chまとめのRSSフィード)
$data['feedurl'][] = 'http://www.calciomatome.net/index.rdf';
$data['feedurl'][] = 'http://blog.livedoor.jp/domesoccer/index.rdf';
$data['feedurl'][] = 'http://football-2ch.com/index.rdf';// ※最後に「/」は付けないでください
$data['feedurl'][] = 'http://blog.livedoor.jp/soccerkusoyarou/index.rdf';
//$data['feedurl'][] = ''; いくらでも追加してください

$rssList = $data['feedurl'];
 
//同時呼び出し
$rssdataRaw = multiRequest($rssList);
 
$count = '0';
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;
                
        	//管理人
        	$myAuther = $myEntry->children("http://purl.org/dc/elements/1.1/")->creator;
                
        	date_default_timezone_set('Asia/Tokyo');
        	$myDateGNU = strtotime($rssDate);
        	$myDate = date('Y/m/d',$myDateGNU);

        	//タイトル
        	$myTitle = $myEntry->title;
        	$outdata[$myDateGNU]['myTitle'] = $myTitle;
        
        	//概要
        	$myDescription = $myEntry->description;
        	$outdata[$myDateGNU]['myDescription'] = $myDescription;
        
        	//リンクURL
        	$myLink = $myEntry->link;
        	$outdata[$myDateGNU]['myLink'] = $myLink;
        
        	//日付
        	$outdata[$myDateGNU]['rssDate'] = $rssDate;
        
        	//管理人
        	$outdata[$myDateGNU]['myAuther'] = $myAuther;
        
        	//ソート用
        	$outdata[$myDateGNU]['myDateGNU'] = $myDateGNU;

        	//出力内容(CSSOK)
        	if(preg_match('/PR:/',$myTitle)) continue;
            
		}
	}
}

$date = array();
foreach($outdata as $key => $row){
	$date[$key] = $row['myDateGNU'];
}

array_multisort($date, SORT_DESC, SORT_NUMERIC, $outdata);

//記事情報取得

$dataList = array();
$dataList = $outdata;    //適当に記事データを取得する処理

//XMLの記事部分作成
$item = "";
foreach($dataList as $value){
	$item .= "<item>n";

	//タイトル
    $itemTitle = $value['myTitle'];
    $item .= "<title>" . $itemTitle . "</title>n";
    
    //概要
    $itemDescription = $value['myDescription'];
    $item .= "<description>" . $itemDescription . "</description>n";

	//リンク
    $itemLink = $value['myLink'];
    $item .= "<link>" . $itemLink . "</link>n";
        
    //管理人
    $itemAuther = $value['myAuther'];
   	$item .= "<author>" . $itemAuther . "</author>n";

	//更新日付
    $itemPubDate = $value['rssDate'];
    $itemPubDate = date('Y年m月d日 H時i分', strtotime($itemPubDate));
    $item .= "<pubDate>$itemPubDate</pubDate>n";

    $item .= "</item>n";

}
    
//XML下部分作成
$rssFooter = <<<RSS
</channel>
</rss>
RSS;

//XML出力
echo $rssHeader.$item.$rssFooter;

//同時呼び出し関数
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;
}
 
?>

これを「index.php」として保存してください。

日付は日本時間に変換して出力しています。
ソースが雑なのはわたしの実力なのであしからず・・・。
あと、このソースを使うことで何かあっても何も保証しません!

というより間違ってる所あったら指摘してほしいです。

実行してみると、こんな感じでテキスト形式で表示されます。
2chmatome13

簡単なソースの解説。

3行目~14行目、
90行目~118行目、
120行目~124行目で、XMLファイルの出力内容を定義しています。

16行目~21行目で、RSSフィードを設定しています。(いくらでも可)

28行目~76行目で、各RSSフィードを解析して、タイトルや更新日などをそれぞれ格納しています。

78行目~83行目で、取得した更新日順に並べ替えてます。

最後に127行目で、作成したRSSフィードを出力(echo)しています。

まとめ。

PHPコードなので環境を用意しないと動作確認できないと思いますが、
一先ずここで区切ります。
(ローカルでPHPの動作確認するには⇒超簡単!PHPプログラムをローカルで動作確認するための環境構築方法を参考にしてください。)

このPHPプログラムは簡単に説明すると、
複数のRSSフィードをまとめて1つのRSSフィードとするプログラムになります。

今回の記事でも分からないことがあれば気軽に聞いてください。

次回は、このRSSフィードとITproで作成したアプリと組み合わせていきます。

[参考サイトまとめ]
RSSのフォーマット・仕様・構造 - RSS1.0、RSS2.0、Content-Type
複数のRSSフィードを高速でまとめる方法
PHP、RSSファイルを作成する。(RSS2.0形式で作ったけど他も多分似たようなもの)

[NEXT]
[Androidアプリ開発]2chまとめアプリ作成への道③~ITproのアプリに自作RSSフィードを流す~