複数サイトのRSS表示について


http://www.zakzak.co.jp/rss/sports/etc_sports.xml
http://number.bunshun.jp/list/rsscolumn
http://gendai.net/articles/feed.rss
http://sankei.jp.msn.com/rss/news/points.xml
の4つのサイトから
'title'要素に
「関塚」又は「なでしこ」又は「柔道」
の3つの文字のあるデータを
日付順に並べて、出力する構文を
http://1811way.com/work008/20120730-02.txt
を元に修正していただけますか。

よろしくお願いします。

回答の条件
  • 1人5回まで
  • 13歳以上
  • 登録:2012/07/30 18:24:24
  • 終了:2012/07/31 17:00:21

ベストアンサー

id:windofjuly No.2

うぃんど回答回数2625ベストアンサー獲得回数11492012/07/30 20:38:49

ポイント300pt

URLを配列に入れておいてループさせるように改良

先頭に形式を整えた日時を加えることでソートできるようにして、
最終出力段階でソート用の先頭の日時を消すという形にしています。

後から並び替えやすいように、$outdata は配列に変更しています。
検索結果件数のカウントは削除しました。

<?php
//ブログなどのRSS FEEDのURL設定
$url_array = array(
    'http://www.zakzak.co.jp/rss/sports/etc_sports.xml',
    'http://number.bunshun.jp/list/rsscolumn',
    'http://gendai.net/articles/feed.rss',
    'http://sankei.jp.msn.com/rss/news/points.xml'
);

// 検索キーワードを設定
$keyword = '/関塚|なでしこ|柔道/';
// 最大出力件数を設定
$num_of_data = 3;

//出力内容を空っぽに初期化(並び替え易いようにするため配列に変えました)
$outdata = array();

// ループ
foreach ($url_array as $url) {
    // 読み込みカウンタ初期化
    $count_of_data = 0; 
    // 読み込み
    $rssdata = simplexml_load_file($url);
    // データの形式によって分岐
    if ($rssdata->getName() == 'feed') {
        // atom の場合の処理
        $children =  $rssdata->children('http://www.w3.org/2005/Atom');
        // 記事ループ
        foreach ($children->entry as $myEntry) { 
            $myTitle = $myEntry->title; //タイトル取得
            if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->published; //日付取得 
                //リンクURL取得
                $myAttr = $myEntry->{'link'}->attributes();
                $myLink = $myAttr['href'];
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    } elseif ($rssdata->getName() == 'rss') {
        // rss2.0 の場合の処理
        // 記事ループ
        foreach ($rssdata->channel->item as $myEntry) {
            $myTitle = $myEntry->title; //タイトル取得
           if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->pubDate; //日付取得
                $myLink = $myEntry->link; //リンクURL取得
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    } elseif ($rssdata->getName() == 'rdf') {
        // rss1.0 の場合の処理
        // 記事ループ
        foreach ($rssdata->item as $myEntry) {
            $myTitle = $myEntry->title; //タイトル取得
            if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->pubDate; //日付取得
                $myLink = $myEntry->link; //リンクURL取得
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    }
}

// 降順並び替え
rsort($outdata);
//最大出力件数分だけ出力する
foreach(array_slice($outdata, 0, $num_of_data) as $output) {
    // 並び替えのための日時部分を消しつつ出力
    echo substr($output, 19);
}
echo "End\n";
他1件のコメントを見る
id:kohhi

早速お返事いただきありがとうございました。
echo substr($output, 19);}
は19->2にして使います。

2012/07/31 16:48:30
id:windofjuly

date関数のYをyに変えると、
date('y/m/d H:i:s', strtotime($myDate))
最初から年は下2桁表記になりますのでsubstrが不要になります。
echo $output;

date関数の詳細は下記参照。
http://php.net/manual/ja/function.date.php

2012/07/31 19:41:23

その他の回答(2件)

id:oil999 No.1

oil999回答回数1728ベストアンサー獲得回数3202012/07/30 20:32:43

ポイント100pt

エラーチェックはしていません。
複数サイトのRSSは、冒頭の配列$rss_urlsに代入してください。いくつでもOKです。

<?php
//ブログなどのRSS FEEDのURL設定
$rss_urls = array(
'http://b.hatena.ne.jp/hotentry?mode=rss&cname=elec',	//rdfのURL例 はてなブックマーク
'http://ideblog.info/feed',								// rss2.0のURL例
'http://number.bunshun.jp/list/rsscolumn'				// atomのURL例
);

//出力データ用
$items[] = array();

// 検索キーワードを設定
$keyword = '/関塚|なでしこ|柔道/ui';
// 最大読み込み件数を設定 
$num_of_data = 5;
// 読み込みカウンタも初期化
$count_of_data = 0; 

foreach ($rss_urls as $url) {
	//設定した読み込み件数分だけ取得できたらループを抜ける
	if ($count_of_data >= $num_of_data) { break; }

	$rssdata = simplexml_load_file($url);
	if ($rssdata->getName() == 'feed') {
		// atom の場合の処理
		$children =  $rssdata->children('http://www.w3.org/2005/Atom');
	    // 記事ループ
	    foreach ($children->entry as $myEntry) { 
	        $items[$count_of_data]['myTitle'] = $myEntry->title; //タイトル取得
	        if (preg_match($keyword, $items[$count_of_data]['myTitle'])) {
	            $items[$count_of_data]['myDate'] = $myEntry->published; //日付取得
	            //リンクURL取得
	            $items[$count_of_data]['myAttr'] = $myEntry->{'link'}->attributes();
	            $items[$count_of_data]['myLink'] = $myAttr['href'];
				$count_of_data++;
			}
        }
	} else if ($rssdata->getName() == 'rss') {
	    // rss2.0 の場合の処理
	    // 記事ループ
	    foreach ($rssdata->channel->item as $myEntry) {
	        $items[$count_of_data]['myTitle'] = $myEntry->title; //タイトル取得
			if (preg_match($keyword, $items[$count_of_data]['myTitle'])) {
            	$items[$count_of_data]['myDate'] = $myEntry->pubDate; //日付取得
            	$items[$count_of_data]['myLink'] = $myEntry->link; //リンクURL取得
				$count_of_data++;
			}
        }
	} else if ($rssdata->getName() == 'rdf') {
	    // rss1.0 の場合の処理
	    // 記事ループ
	    foreach ($rssdata->item as $myEntry) {
	        $items[$count_of_data]['myTitle'] = $myEntry->title; //タイトル取得
	        if (preg_match($keyword, $items[$count_of_data]['myTitle'])) {
	            $items[$count_of_data]['myDate'] = $myEntry->pubDate; //日付取得
	            $items[$count_of_data]['myLink'] = $myEntry->link; //リンクURL取得
				$count_of_data++;
			}
        }
    }
}

//出力内容を空っぽに初期化 
$outdata = ''; 
foreach ($items as $item) {
	//出力内容にタイトル(リンク付)を入れる 
	$outdata .= '<h3 class="posttitle"><a href="' . $item['myLink'] . '">' . $item['myTitle'] . '</a></h3>' . "\n"; 
	//出力内容に日付けを入れる 
	$outdata .= '<p class="postdate">' . $item['myDate'] . '</p>' . "\n"; 
}

//echo $rssdata->getName() . "\n";
echo $keyword . 'の検索結果は' . $count_of_data . "件です\n";
echo $outdata;	//全部出力する
echo "End\n";
?>
id:kohhi

早速お返事いただきありがとうございました。

2012/07/31 16:46:56
id:windofjuly No.2

うぃんど回答回数2625ベストアンサー獲得回数11492012/07/30 20:38:49ここでベストアンサー

ポイント300pt

URLを配列に入れておいてループさせるように改良

先頭に形式を整えた日時を加えることでソートできるようにして、
最終出力段階でソート用の先頭の日時を消すという形にしています。

後から並び替えやすいように、$outdata は配列に変更しています。
検索結果件数のカウントは削除しました。

<?php
//ブログなどのRSS FEEDのURL設定
$url_array = array(
    'http://www.zakzak.co.jp/rss/sports/etc_sports.xml',
    'http://number.bunshun.jp/list/rsscolumn',
    'http://gendai.net/articles/feed.rss',
    'http://sankei.jp.msn.com/rss/news/points.xml'
);

// 検索キーワードを設定
$keyword = '/関塚|なでしこ|柔道/';
// 最大出力件数を設定
$num_of_data = 3;

//出力内容を空っぽに初期化(並び替え易いようにするため配列に変えました)
$outdata = array();

// ループ
foreach ($url_array as $url) {
    // 読み込みカウンタ初期化
    $count_of_data = 0; 
    // 読み込み
    $rssdata = simplexml_load_file($url);
    // データの形式によって分岐
    if ($rssdata->getName() == 'feed') {
        // atom の場合の処理
        $children =  $rssdata->children('http://www.w3.org/2005/Atom');
        // 記事ループ
        foreach ($children->entry as $myEntry) { 
            $myTitle = $myEntry->title; //タイトル取得
            if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->published; //日付取得 
                //リンクURL取得
                $myAttr = $myEntry->{'link'}->attributes();
                $myLink = $myAttr['href'];
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    } elseif ($rssdata->getName() == 'rss') {
        // rss2.0 の場合の処理
        // 記事ループ
        foreach ($rssdata->channel->item as $myEntry) {
            $myTitle = $myEntry->title; //タイトル取得
           if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->pubDate; //日付取得
                $myLink = $myEntry->link; //リンクURL取得
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    } elseif ($rssdata->getName() == 'rdf') {
        // rss1.0 の場合の処理
        // 記事ループ
        foreach ($rssdata->item as $myEntry) {
            $myTitle = $myEntry->title; //タイトル取得
            if (preg_match($keyword, $myTitle)) {
                $myDate = $myEntry->pubDate; //日付取得
                $myLink = $myEntry->link; //リンクURL取得
                //出力内容にタイトル(リンク付)と日付を入れる
                array_push($outdata,
                    date('Y/m/d H:i:s', strtotime($myDate))
                    . '<h3 class="posttitle"><a href="' . $myLink . '">' . $myTitle . '</a></h3>' . "\n"
                    . '<p class="postdate">' . $myDate . '</p>' . "\n"
                ); 
                //設定した読み込み件数分だけ取得できたらループを抜ける
                if (++$count_of_data  == $num_of_data) { break; }
            }
        }
    }
}

// 降順並び替え
rsort($outdata);
//最大出力件数分だけ出力する
foreach(array_slice($outdata, 0, $num_of_data) as $output) {
    // 並び替えのための日時部分を消しつつ出力
    echo substr($output, 19);
}
echo "End\n";
他1件のコメントを見る
id:kohhi

早速お返事いただきありがとうございました。
echo substr($output, 19);}
は19->2にして使います。

2012/07/31 16:48:30
id:windofjuly

date関数のYをyに変えると、
date('y/m/d H:i:s', strtotime($myDate))
最初から年は下2桁表記になりますのでsubstrが不要になります。
echo $output;

date関数の詳細は下記参照。
http://php.net/manual/ja/function.date.php

2012/07/31 19:41:23
id:Cherenkov No.3

Cherenkov回答回数1502ベストアンサー獲得回数4922012/07/30 21:58:06

ポイント100pt

質問者にとってより価値のある回答を提供したいと思っているので、敢えてSimplePieというライブラリを使った例を示します。
こういったライブラリを使えばatom,rss1.0,rss2.0などの違いを吸収してくれて、メソッド一発で必要な物を取得できるのでおすすめです。
フィードリーダーを1から作るのが目的ではないですよね?


使い方
SimplePie Documentation: Setup and Getting Started を参考にすすめる。

  1. SimplePie: Super-fast, easy-to-use, RSS and Atom feed parsing in PHP. download&解凍。
  2. libraryディレクトリとautoloader.phpをコピー。
  3. cacheディレクトリを作成。
  4. cacheディレクトリのパーミッションを777にする。

以下の様な構成になる。

  • cacheディレクトリ
  • libraryディレクトリ
  • autoloader.php
  • hateq.php (下記のコードをutf-8で保存)

<?php 
require_once './autoloader.php';

// 検索キーワードを設定
$keyword = '/関塚|なでしこ|柔道/u'; //uフラグでパターンがutf-8であることを知らせる
// 最大読み込み件数を設定 
$num_of_data = 5; //今回はキーワードにマッチしたエントリの内の最大表示件数として利用

$feedList = array(
	'http://www.zakzak.co.jp/rss/sports/etc_sports.xml',
	'http://number.bunshun.jp/list/rsscolumn',
	'http://gendai.net/articles/feed.rss',
	'http://sankei.jp.msn.com/rss/news/points.xml'
);

function pr($var) {
	echo '<pre>'; print_r($var); echo '</pre>';
}

$feed = new SimplePie();
$feed->set_cache_location("./cache"); // キャッシュディレクトリ指定
$feed->set_cache_duration(600);
$feed->set_feed_url($feedList);
//$feed->set_item_limit(5); フィード全体のリミット
$success = $feed->init();
$feed->handle_content_type();


header('Content-Type:text/html; charset=UTF-8');

$result_items = array();

if ($success) {
	//キーワードにマッチするエントリを集める。
	foreach($feed->get_items() as $item) {
		if (preg_match($keyword, $item->get_title())) {
			$result_items[] = $item;
		}
	}
	echo '<p>' . $keyword . ' の検索結果は ' . count($result_items) . ' 件です<br>(最大読み込み件数の設定によっていくつか見えないはず)</p>';

	//エントリー表示部
	foreach($result_items as $i => $item) {
		if ($i < $num_of_data) {
			//エントリのフィードタイトルは $item->get_feed()->get_title()
			echo '<h3 class="posttitle"><a href="' . $item->get_permalink() . '">' . $item->get_title() . '</a>' . $item->get_feed()->get_title() . '</h3>';
			//echo '<h3 class="posttitle"><a href="' . $item->get_permalink() . '">' . $item->get_title() . '</a></h3>';
			echo '<p class="postdate">' . $item->get_date('Y/m/d H:i:s') . '</p>';
		}
	}
} else {
	echo 'error';
}


参考

他4件のコメントを見る
id:Cherenkov

http://q.hatena.ne.jp/1343721480 の質問にある「description要素」の有無についても
get_description() このメソッド使えばいいわけだし。

2012/07/31 18:26:39
id:kohhi

コメントありがとうございます。
get_description() メソッド、勉強してみます。

2012/07/31 18:55:45

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません