MagpieRSSで他サイトのエントリーを表示


自分のブログに他の人のブログの更新情報を載せるのに一般的な方法はblogpeopleなどのサービスを利用してjavaスクリプトを貼り付けたりします。

私も右下に同サービスを利用して便利に活用させていただいています。

ですが、こういったサービスはデザインや表示方法などに制約があり自分の思ったとおりに表示させることができなかったりします。

MagpieRSSというものがありまして、これはRSSを持ってきて表示してくれる優れものプログラム?なんです。
説明はこちらにあるとおり

PHP で使える RSS パーサー。 PHP でリモートの RSS を取得、解析、そしてキャッシュまで全部やってくれる。RSS0.9 と RSS1.0 に対応。

なんて感じです。

実はリニューアル前の自分のホームページにものブログを表示させたくて利用してましたが、リニューアル後blogpeopleなどもあるので必要性を感じなくなりつかっていませんでした。

そんな感じだったんですけども、Blade-xさんのところの記事を発見。

複数のRSSを一括で表示して、最近の記事にNEWマークまでつけられそうです。

これを使えばすかじゃんブログ仲間の記事をサイト内にかっこよく(むしろなじむように)表示できそうだぞということでトライいたしました。

ほぼBlade-xさんのソースを丸写しですが本文を表示させないのでそこの部分を若干直しました。

それと表示する文字数を切り落とすように処理する部分で文字表示が乱れてしまっていたのでmb_strimwidth()に変更してみたらうまく表示できました。

どうしてもできなかったのがエントリータイトルのツールチップに記事の内容を表示させるところで改行コードが残ってしまっているらしく文字が詰まってくれないところです。

いろいろとやっては見たものの素人の私には限界のようであきらめました。

でも、全体的にはかなり満足。

なかでもちょっと気に入っているのは本当にRSSを引っ張ってきたときはブログ名の横にgetとでて、キャッシュを表示させてるときにはcacheと表示させるところです。

今は5つのRSSを引っ張ってきていますが意外と表示が速くてびっくり!もちろんキャッシュのときはもっと早いんですけどね。

2006/5/21 追記

ソースを見直しまして間違いを訂正したのと改行コードを削除した形にできました。

以下ソースコード


<?php
// エラー抑制
error_reporting(E_ERROR);

require_once '(magpieRSSのパス)/magpie/rss_fetch.inc';
require_once '(magpieRSSのパス)/magpie/rss_utils.inc';

// 取得するitems 数、分類毎に取得する数を変えたい場合は分類別に変数を増やし数値を設定する
$num_items = 3;

// 更新と見なす日数
$days = 3;

// Magpieの設定
define('MAGPIE_OUTPUT_ENCODING','UTF-8'); // 文字コード
define('MAGPIE_FETCH_TIME_OUT', 5); // 接続をタイムアウトする時間
define('MAGPIE_CACHE_ON', true); // 取得するRSSをcacheするかしないかfalseだとしない
define('MAGPIE_CACHE_DIR', '(magpieRSSのパス)/magpie/cache'); // cacheディレクトリ
define('MAGPIE_CACHE_AGE', 3600); // Magpieのcacheの寿命

// dcdateが無くてpubdateがある時(FeedBurnerとか)
// "Fri, xx Dec 2xxx xx:xx:xx +0900"みたいなフォーマットになってたらMagpieの"rss_utils.inc"で
// 対応出来るフォーマットに変換する("rss_utils.inc"を参考にしてます)
$pat = "/^(?:\D{3})\,\s(\d{2})\s(\D{3})\s(\d{4})\s(\d{2}):(\d{2}):(\d{2})\s([-+]\d{4}|\D{3})/";
$month_list = array(
"Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04", "May" => "05", "Jun" => "06",
"Jul" => "07", "Aug" => "08", "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12"
);

function conv_date($date_str) {
global $pat, $month_list;

if (preg_match($pat, $date_str, $match)) {
list($year, $month, $day, $hours, $minutes, $seconds, $tz) =
array($match[3], $match[2], $match[1], $match[4], $match[5], $match[6], $match[7]);
foreach($month_list as $conv_month=>$replace) {
if(preg_match("/^$conv_month$/", $month)){
$month = $replace;
break;
}
}
$date_str = $year . '-' . $month . '-' . $day . 'T' . $hours . ':' . $minutes . ':' . $seconds . $tz;
}
return $date_str;
}

// 読み込んだRSSデータのタイトルや概要にタグがあったら取り除き、メタ文字はHTMLエンティティに変換する
function convert_sp_char ($char,$arg) {
if (preg_match("/<|>|\"|&/", $char)) {
if ($arg == "2") {
$char = strip_tags("$char");
}
$char = htmlspecialchars("$char");
}
if ($arg == "1") {
$char = mb_strimwidth($char, 0, 30,"…",utf8); // タイトル文字数
}
return $char;
}

function convert_desc ($desc) {
$desc = trim ($desc);
$desc = nl2br ($desc);
$desc = strip_tags($desc);
$desc = str_replace("\n", "", $desc); //改行コードの削除
$desc = mb_strimwidth ($desc, 0, 150,"…",utf8); // 概要(description)の表示する文字数
return $desc;
}

// RSSの日付と今日の日付を比較し新しければ「New.gif」を出力
function diff_date ($date,$days) {
$rssdate = strtotime("$date");
$today = strtotime(date("Y/m/d H:i"));
$diff = date("U", ($today - $rssdate))/86400;
if ($days > $diff) {
echo ' <img src="http://www.eternalheart.com/img/upnew.gif" alt="New" />';
}
return $date;
}

// cacheを表示している場合
$rss_cache = '<span class="cache"> [cache]</span>';

// RSSを新たに取得した場合
$rss_get = '<span class="cache"> [get!]</span>';

// Magpieのエラーメッセージと一緒に表示
$e_message = <<<DATA
<img src="error.png" alt="It was unacquirable." title="It was unacquirable." width="80" height="15" /></a> <h3>It was unacquirable.</h3>
<ul>
<li>RSS FEED を取得できませんでした、詳細は下記。</li>
<dd>Error Message!<br />
DATA;

?>

<?php
// RSSを取得したいサイトのURLリスト
$men = array (
"http://suka.xoozy.com/index.xml",
"http://natchan.blog4.fc2.com/?xml",
"http://asuasu.blog4.fc2.com/?xml",
"http://nojic.blog4.fc2.com/?xml",
"http://hitomitic.blog4.fc2.com/?xml",
"http://gatcho.blog4.fc2.com/?xml",
"http://nz.xoozy.com/?mode=rss",
"http://spaces.msn.com/takashifuse/feed.rss",
"http://blog.livedoor.jp/shakura1223/index.rdf"
);
?>

<!-- RSSを取得する為の部分、複数の分類をしたい場合はここから下の部分を別名のファイルにし
それぞれのマークアップした部分で読み込む(includeとかrequireで) -->

<?php
foreach ($men as $url) {
$rss = fetch_rss($url);
// RSSからサイト名を取得
$title = $rss->channel['title'];
if (isset($title)) {
$title = convert_sp_char($title, "3");
$site = $rss->channel['link'];
// キャッシュから取得した場合
if ($rss->from_cache == 1) {
$if_cache = $rss_cache;
} else {
$if_cache = $rss_get;
}
// サイト名を表示しサイトURLにリンクするRSSファイルへのリンクはFeedBottonで
echo <<<DATA
<a class="sukatitle" href="{$site}" title="{$title}" target="_blank">{$title}</a> {$if_cache}\n<ul>

DATA;
// "$rss->items"の次の数値を変更すると何番目のアイテムから表示するか変更できる、$num_itemsは取得するアイテム数
$rss->items = array_slice($rss->items, 0, $num_items);
foreach ($rss->items as $item ) {
$title = $item['title'];
$quote_title = convert_sp_char($title, "3");
$title = convert_sp_char($title, "1");
$url = $item['link'];
if (isset($item['dc']['date'])) {
$date = date("Y/m/d H:i", parse_w3cdtf($item['dc']['date']));
} elseif (isset($item['pubdate'])) {
if (preg_match($pat, $item['pubdate'])) {
$date = date("Y/m/d H:i", parse_w3cdtf(conv_date($item['pubdate'])));
} else { // "$item['pubdate']"を上で変換出来なかった時はそのまま表示
$date = $item['pubdate'];
}
} else {
$date = "A refix date is unacquirable.";
}
// RSSにdescriptionがあるか確認し、ない場合時は表示しない
if (isset($item['description'])) {
$desc = $item['description'];
$desc = convert_desc($desc);
}
$title = convert_desc($title);
echo '<li>└ <a href="' . $url . '" title="' . $desc . '" target="_blank">' . $title . '</a>';
// 日付フォーマットが任意の物でない場合は更新日の比較をしない
if (preg_match("/^\d{4}\/\d{2}\/\d{2}\s?/", $date)) {
diff_date($date,$days);
}
echo "</li>\n";
}
echo "</ul>\n";
} else { // MagpieRSSのエラーを表示
echo '<a href="' . $url . '">' . $e_message . magpie_error() . "</li>\n</ul>\n";
}
}
?>

URL : http://www.eternalheart.com/cgi/mt/mt-tb.cgi/233

大変お手数なんですが、、
もし、お手間でなければ、
このソースのままでは、RSSが引っ張られてくるときに、UTFのままみたいで、、、中国語のHPみたいになってしまいます。。
このソースないで、SJISに変換することって可能なんでしょうか。

教えてください。お願いします。

はじめまして。
ソースコード内の
define('MAGPIE_OUTPUT_ENCODING', 'UTF-8'); 内の UTF-8 となっている部分を、RSS を表示させるファイルの文字コードに合わせて下さればよろしいかと思います。

ありがとうございます。
早速ためしてみたのですが、やっぱし、UTF-8で出力されてしまいましたぁ。。

良いお知恵があれば、お願いいたします。

なんとか自己解決いたしました。
問題点は、先のコードをWinのメモ帳で開いていたので、上書き保存する際に自動的にSJISになっていることでした。。

適当なエディタでUTF-8で保存し、inflameでSJISにページに読み込ませたら問題なく表示できました。
ありがとうございました。

magpierssのソース公開有難うございます。
検索をしてこちらにきました。

ひとつ質問なんですが、記事タイトルの前に時間を表示させたいのですがどのようにすれば出来るのでしょうか?


<li>○○<a href="' . $url . '" title="' . $desc . '" target="_blank">' . $title . '</a>';

○○の部分に記事の時間取得をして付け足したいです。
忙しい中すいません、助けて下さい><。
$dateなどと記述しても$dateがそのまま表示されてしまいました。

時間表記は無事に出来ました。
お手数かけました。

最後に取り組んでいるのが、更新順に上から表示させたいのですが、
下の方にある、echo '<ul><li>(略)をどのようにソートしてあげればいいでしょうか。
よろしければアドバイスをお願いします。

No.651の拓さんのコメントへの返信

拓さま

解決したとのことでよかったです。
一応、僕なりに考えたやり方です。

} else { // "$item['pubdate']"を上で変換出来なかった時はそのまま表示
$date = $item['pubdate'];
}
$r_date = date("Y/m/d", $date);
} else {
$date = "A refix date is unacquirable.";
}

$dateを元に表示用の$r_dateを作成します。
その際date関数で表示の仕方を表示したい形に変えます。
"Y/m/d"は2008/01/05のような形です。

表示させたい場所に$r_dateを追加します。

<li>'.$r_date.'<a href="' . $url . '" title="' . $desc . '" target="_blank">' . $title . '</a>';

これで表示されると思います。

また、ソート方法については調べたのですが、ごめんなさいよく分かりませんでした。

こちらの記事などが参考になるかもと思いました。
http://scrapbook.ameba.jp/network_book/entry-10018566158.html

あまりお力になれず申し訳ないです。

tetsuさん、わざわざ本当にありがとうございますm(_ _"m)ペコリ。

ソートの方法でわかりましたら、また書き込み報告させて頂きます。
本当に感謝しております。

tetsuさん、この間はアドバイス等有難うございました。
ソートは色々やり方など聞いたのですが出来ませんでした;;。

色々ソートの出来るようなソースを探していたら、ごちゃまぜRSSリーダーを発見しました。
http://www.vector.co.jp/soft/cmt/unix/net/se334908.html

こちらは記事の表示件数を指定(ソースを加えて)してあげたらソートしてくれました。

問題がひとつだけありまして、各サイトのRSSの時間を取得してくれませんでした。
公式サイトを見ると、時間の取得はdate_timestampを使えば出来るようなことが書いてあるんですが、

$date_timestamp = $item[date_timestamp];

$date = Date("Y/n/j G:i",$date_timestamp);

$rssreader["{$date_timestamp}"];

echo "$date $title ($p_title)\n";

1970/1/1 9:00と表示されてしまいました。

もうひと頑張りなんですが中々難しいですね。
magpierssはキャッシュが使えるのでお気に入りです。

楽天アフィリエイト

eternalheart.com

サイトのモバイル対応

サイトのモバイル対応を行いました。

携帯電話
http://www.eternalheart.com/m/

iPhone/iPod touch
http://www.eternalheart.com/i/

よろしければどうぞ~~