Hatena::ブログ(Diary)

imakamiのメモ

2008-12-17

ニコニコ生放送のコメントを取得しようとした…けど失敗

| 21:37 | ニコニコ生放送のコメントを取得しようとした…けど失敗を含むブックマーク

ニコニコ動画でユーザーが生で動画を配信できるようになっていました。その名も「ニコニコ生放送」。

いつからできるようになったんだろう。

普通の動画コメントの取得は

http://yusukebe.com/tech/archives/20070803/124356.html

みたいにするといいみたい。

それを真似する。

が、調べてみるとちょっと違う。

以下自分で調べてみたのでちょっと間違ってるかもです。

http://www.nicovideo.jp/api/getflv?v=

のところが

http://live.nicovideo.jp/api/getplayerstatus?v=lv(ライブのアドレス)

になる。

プログラム内でログインした後、上のアドレスにアクセスすると、その部屋の詳細が帰ってくる。

こんなかんじ。

<getplayerstatus status="ok" time="1229468107"><stream><id>lv9097</id><watch_count>50</watch_count><comment_count>116</comment_count><bourbon_url/><full_video/><after_video/><befor_video/><ichiba_notice_enable>1</ichiba_notice_enable><comment_lock>0</comment_lock><background_comment>0</background_comment><base_time>1229466785</base_time><contents_list><contents id="main" disableAudio="0" disableVideo="0" start_time="1229466785">rtmp:liverepeater:rtmp://clo2u.live.nicovideo.jp:1935/publicorigin/lv9097</contents></contents_list></stream><user><room_label>貸部屋</room_label><room_seetno>50</room_seetno><nickname>siokuma</nickname><is_premium>1</is_premium><user_id>5694684</user_id></user><rtmp><url>rtmp://lss113.live.nicovideo.jp:1935/liveedge</url><ticket>5694684:lv9097:0:1229468107:9403f81c573d4995</ticket></rtmp><ms><addr>msg104.live.nicovideo.jp</addr><port>2813</port><thread>1000013644</thread></ms></getplayerstatus>

で、今度は上の中のメッセージサーバのアドレスらしきものとthreadに注目する。

そこへ次のようなxmlをPOSTしてみる。

<thread thread="スレッド番号" version="20061206" res_from="-10" />

すると、最新のコメント10件が取得できるはず…なんですが。

やってみると、ほとんどの場合失敗します。

しかしたまに成功する場合もあります。十数回に一回くらいでしょうか。

今のところ成功するパターンと失敗するパターンの違いがわかりません。

成功バージョン:

<packet><thread last_res="14" resultcode="0" revision="1" server_time="1229516667" thread="1000014556" ticket="0x9e94c08"/><chat anonymity="1" date="1229515975" mail="184" no="5" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="24587">生飯動画見たいなもんですねw</chat><chat anonymity="1" date="1229516046" mail="184" no="6" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="31606">リアルの職業ゎ??</chat><chat anonymity="1" date="1229516132" mail="184" no="7" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="40270">とりあえず飲みましょうよ!</chat><chat anonymity="1" date="1229516147" mail="184" no="8" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="41743">強いですか?</chat><chat anonymity="1" date="1229516284" mail="184" no="9" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="55432">ドンペリドンペリ!!</chat><chat anonymity="1" date="1229516298" mail="184" no="10" thread="1000014556" user_id="KdSB0M1pZRgh_2Rwl_MbYQ7y-lY" vpos="56898">これうまいの?</chat><chat anonymity="1" date="1229516315" mail="184" no="11" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="58521">金麦飲んでますb</chat><chat anonymity="1" date="1229516341" mail="184" no="12" thread="1000014556" user_id="KdSB0M1pZRgh_2Rwl_MbYQ7y-lY" vpos="61204">へえええええ</chat><chat anonymity="1" date="1229516404" mail="184" no="13" thread="1000014556" user_id="bDAyfalW2chWqmxdrNXgdon5J-Q" vpos="67400">ちょっと客増やしてきますww(ぇ</chat><chat anonymity="1" date="1229516658" mail="184" no="14" premium="1" thread="1000014556" user_id="uT4uKjFCa1rK-KyGvgyj5SvoRlM" vpos="92796">いらっしゃいませ〜@主</chat></packet>

失敗バージョン:

<packet><thread resultcode="0" revision="1" server_time="1229516639" thread="1000014564" ticket="0x848c778"/></packet>

resultcode="0"なのに…?

そして現在のPythonソース:

import cookielib
import urllib2
import urllib
from xml.dom.minidom import parseString
import sys

login_url = "https://secure.nicovideo.jp/secure/login"
api_url = "http://live.nicovideo.jp/api/getplayerstatus?v=lv"
password = "ぱすわーど"
username = "ゆーざーねーむ"

def getText(elm):
	nodelist = elm.childNodes
	rc = ''
	for node in nodelist:
		if node.nodeType == node.TEXT_NODE:
			rc = rc + node.data
	return rc

def login(mail, password):
    query = {"mail":mail, "password":password}
    query = urllib.urlencode(query)
    response = urllib2.urlopen(login_url, query)

if len(sys.argv) == 1:
	print 'please input number'
	exit()
movieID = sys.argv[1]
cookie_jar = cookielib.LWPCookieJar()
cookie_handler = urllib2.HTTPCookieProcessor(cookie_jar)
opener = urllib2.build_opener(cookie_handler)
opener.addheaders = [('Referer','http://www.smilevideo.jp/')]
opener.addheaders = [('User-agent','Mozilla/4.0 (compatible; MSIE 6.0; Linux)')]
urllib2.install_opener(opener)

login(username,password)
response = urllib2.urlopen(api_url + movieID)
movieinfo = urllib.unquote(response.read())

dom = parseString(movieinfo)
xmlroot = dom.documentElement
thread = 'None'
addr = 'None'
for element in xmlroot.getElementsByTagName('ms'):
	for node in element.childNodes:
		if node.nodeName == 'thread':
			thread = getText(node)
		elif node.nodeName == 'addr':
			addr = getText(node)
if (thread or addr) == 'None':
	print 'invalid address'
	exit()
else:
	print thread,addr

xml = '<thread thread="'+thread+'" version="20061206" res_from="-10" />'

req = urllib2.Request('http://'+addr+'/api/' , data=xml)
res = urllib2.urlopen(req)
res2 = res.read()
print res2
ch = []
dom = parseString(res2)
xmlroot = dom.documentElement
for element in xmlroot.getElementsByTagName('chat'):
	ch.append(getText(element))
for line in ch:
	print line

実はもうとっくに誰かが発見済みとかいうオチでしょうか。気になります。

追記:

おとなり日記のリンク先のNicoLiveChatというソフトが目的の動作をしてるっぽい。

きちんとやれば普通にできそう。

どうすればいいんだろう…。

ExceptionErrorExceptionError 2008/12/18 18:25 ニコニコ動画のコメントサーバーはHTTP通信なんですが、ニコニコ生放送のコメントサーバーはSocket通信なのでアドレスだけ変えても動きません。
Pythonの知識は持ち合わせていないのでコードはわかりかねますが、APIから返ってきたaddrとportに接続して<thread thread="'+thread+'" version="20061206" res_from="-10" />を送りつければコメントが返ってきますよ。

imakamiimakami 2008/12/19 01:43 アドバイスありがとうございます。
ネットワークのことはほとんど知らないに等しいですが調べながらやってみます。