PHPでRSSを読んでみます。
ニコニコ生放送RSS http://live.nicovideo.jp/recent/rss から
番組表 http://c-loft.com/nico/を生成させてみました。
ニコニコ生放送RSS1ページには、18番組が掲載されています。
URL末尾にクエリ”?p=ページ数”を付加することで1ページ目以降のページにアクセスできます。
RSSの構成を以下に示します。
総番組数(nicolive:total_count)の値から、
全番組情報を取得するために読み込むべきページ数が分かります。
<?xml version="1.0" encoding="utf-8"?> <rss version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:nicolive="http://live.nicovideo.jp/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title>ニコニコ生放送</title> <link>http://live.nicovideo.jp/</link> <description>ニコニコ生放送は生中継にリアルタイムでコメントを付けられる、ニコニコ動画のコンテンツです。</description> <language>ja-JP</language> <copyright>niwango,inc. All rights reserved.</copyright> <nicolive:total_count>2163</nicolive:total_count> : :ここに<item>番組情報</item>が列挙される(後述) : </channel> </rss>
1番組の情報は以下のように<item>タグ内に載っています。
<item> <title>番組タイトル</title> <link>http://live.nicovideo.jp/watch/lv01234567</link> <guid isPermaLink="false">lv01234567</guid> <pubDate>Tue, 12 Oct 2010 19:00:00 +0900</pubDate> <description>放送概要</description> <category>カテゴリー</category> <media:thumbnail url="http://icon.nimg.jp/community/s/co472398.jpg?1286488149" width="64" height="64" /> <dc:creator>コミュニティ名/coXXXXXXX</dc:creator> <nicolive:community_name>コミュニティ名</nicolive:community_name> <nicolive:community_id>coXXXXXXX</nicolive:community_id> <nicolive:num_res>コメント数</nicolive:num_res> <nicolive:view>来場者数</nicolive:view> <nicolive:member_only>コミュ限かどうか</nicolive:member_only> <nicolive:type>放送カテゴリ</nicolive:type> <nicolive:owner_name>生主名</nicolive:owner_name> </item>
PHPでRSSを読むためにsimplexml_load_file関数を利用しました。
番組情報は$xml->channel->itemをforeach処理で読めます。
$xml = simplexml_load_file('http://live.nicovideo.jp/recent/rss'); if($xml == false) { /* メンテ中等で読めなかったときの対処をここで行ないます */ echo 'RSSが取得できませんでした。<br>'; echo 'ニコニコ生放送のメンテナンス中かもしれません<br>'; return; } /* 以降、RSSの中身を読みます */ foreach($xml->channel->item as $item) { /* 名前空間 */ $media = $item->children('http://search.yahoo.com/mrss/'); $nicolive = $item->children('http://live.nicovideo.jp/'); /* 公式生放送、チャンネル生放送を除外してみる */ if($nicolive->type != 'community') { continue; } /* 取得した情報を表示するサンプル */ echo "$item->pubDate"."n"; /* 開始時刻 */ echo "$item->category"."n"; /* カテゴリ */ echo "$item->link"."n"; /* URL */ echo "$item->title"."n"; /* タイトル */ echo "$nicolive->owner_name"."n"; /* 生主名 */ echo "$nicolive->num_res"."n"; /* コメント数 */ echo "$nicolive->view"."n"; /* 来場者数 */ echo "$nicolive->community_id"."n"; /* コミュID */ echo "$nicolive->community_name"."n"; /* コミュ名 */ }
URL末尾に?tab=タブ名クエリをつけることでカテゴリごとの番組情報を取得できます。
common:一般
try:やってみた
live:ゲーム
req:動画紹介
r18:R-18
face:顔だしON
totu:凸待ちON
park:遊園地ON
現在自分も、PHPの勉強を兼ねて ロフトさんの作ったような番組表を作成しているのですが、ロフトさんの番組表のように全ての番組を取得することができません
この記事で書かれているようにロフトさんの番組取得プログラムは毎回、現在の生放送数を元に
RSSの全ページをクロールしているのでしょうか?
それとも前回のクロールの最後に取得した番組番号などの目印となるものが見つかるまでクロールしているのでしょうか?
ロフトさんの番組取得プログラムのクロール方法を教えていただけると幸いです
よろしくお願いします
>#1 by 社会人二年目さん
こんにちわ。
はい、現在の生放送数を元に全ページを取得しています。
ページ数は以下で指定できます。
http://live.nicovideo.jp/recent/rss?p=ページ数
返信ありがとうございます
ロフトさんは、”毎回”全ページをクロールされているということですが
もし、放送数が4000を超えている場合、
223ページ以上クロールすることになります
このクロール数はいくらなんでも多いと思うのですが
ロフトさんの番組取得プログラムは、クロールする際に番組取得に加え”更新処理”も一緒にやっているから全ページをクロールする必要があるのでしょうか?
それとも他に全ページをクロールしなくてはいけない理由などがあるのでしょうか?
素朴な疑問なのですが教えてください
>#3 by 社会人二年目さん
こんちちわ。
はい、ご指摘のとおり、ユーザが番組表サイトにアクセスするたびに
毎回全ページを取得しています。理由は実装が容易なためですw
しかし、全番組をひとつのテーブルに表示しているのは、
番組表が生成されるまで待たされるため、実用的でないと認識しています。
ユーザのアクセス時でなく、定期的にRSSを取得しておき、
いったん情報をDBに蓄積するなどしたものを、
ちくわちゃんhttp://www.chikuwachan.com/live/の番組表のように、
50番組程度ずつに分けて表示するのがよいのかなと思いつつ、
現状は手を付けていない状態です。
(RSS定期取得頻度によりますが、視聴者数、コメント数の情報は最新値に比べ、若干古くなります。)
ユーザアクセス毎に全番組取得を行っているにも関わらず
番組表のレスポンスが早いのに驚きました
丁寧かつ、簡潔にクローラーのクロール方法を教えていただきありがとうございます
>#5 by 社会人二年目さん
いえいえ、コメントを頂くことで私も勉強になります。
少しでもご参考になりましたら幸いです。
ピンバック:ニコ生APIの仕様について | 備忘録