ニコニコ動画の公式動画に投稿されたコメントの取得方法 (一部修正)

前回、公式動画のコメントを取得するために threadkey と force_184 という属性が必要であると書きましたが、どうも、この属性は固定ではないようです。


具体的に説明すると force_184 の値(何のための値かは不明)が存在しない場合がありました。
試しにその動画で force_184 を設定してコメントを取得しようとしてみましたが見事にエラーが返ってきました (-ω-;)ウーム


まだ他にも確認していない属性があるかもしれないので、getthreadkey のレスポンスをそのまま変換して受け渡すように修正しました。
後、よく見ると getflv で取得した needs_key という値が スレッドキーが必要かどうかの判定になっているようなので、その部分も一緒に修正しました。


修正したPythonでのサンプル

#!/usr/bin/python
# -*- coding: utf-8 -*-

import httplib,urllib
import re
import cgi

mailAddress = "メールアドレス"
passWord = "パスワード"

videoid = "so6763675"# 天体戦士サンレッド FIGHT. 01
#videoid = "sm9"# 新・豪血寺一族 -煩悩解放 - レッツゴー!陰陽師

headers = {'User-Agent':'Mozilla/5.0 (Windows; U; Windows NT 6.1; ja; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)',
    'Accept': '*/*',
    'Accept-Language': 'ja,en-us;q=0.7,en;q=0.3',
    'Accept-Charset': 'UTF-8,*',
    'Connection': 'keep-alive',
    'Keep-Alive': '300',
    'Cookie': '; '}

# 動画ページ
if videoid[0:2] == "so":
    conn = httplib.HTTPConnection('www.nicovideo.jp', 80)
    conn.request('GET', '/watch/%s' % videoid, '', headers)
    rs = conn.getresponse()
    body = rs.read()
    print body
    rs.close()
    conn.close()

    if rs.status == 302:
        mc = re.compile('/watch/(.*)').search(rs.getheader('Location'))
        print 'videoid=', videoid, "->", mc.group(1)
        videoid = mc.group(1)


# ログイン処理
post_dict = {'next_url': '',
    'submit': '',
    'mail': mailAddress,
    'password': passWord
    }
headers['Referer'] = 'http://www.nicovideo.jp/'
headers['Content-type'] = 'application/x-www-form-urlencoded';
conn = httplib.HTTPSConnection('secure.nicovideo.jp')
conn.request('POST', '/secure/login?site=niconico', urllib.urlencode(post_dict), headers)
rs = conn.getresponse()
mc = re.compile('(user_session=(?!deleted)[^;]*);?').search(rs.getheader('Set-Cookie'))
user_session = mc.group(1)
headers['Cookie'] = user_session
rs.read()
rs.close()
conn.close()

print "user_session=", user_session


# 動画ページに接続し、動画サーバ、
conn = httplib.HTTPConnection('www.nicovideo.jp', 80)
conn.request('GET', '/watch/%s' % videoid, '', headers)
rs = conn.getresponse()
body = rs.read()
rs.close()
conn.close()
mc = re.compile(r'nicoplayer\.swf\?ts=(\d+)').search(body)
video_ts = int(mc.group(1))

print "ts=", video_ts

# 動画情報の取得
conn = httplib.HTTPConnection('www.nicovideo.jp', 80)
conn.request('GET', '/api/getflv/%s' % videoid, '', headers)
rs = conn.getresponse()
body = rs.read()
rs.close()
conn.close()
qs = cgi.parse_qs(body)
thread_id = qs["thread_id"][0]
user_id =  qs["user_id"][0]
mc = re.compile(r'&ms=http%3A%2F%2F(.+?)\.nicovideo\.jp(%2F.+?)&').search(body)
message_server = urllib.unquote_plus(mc.group(1))
message_path = urllib.unquote_plus(mc.group(2))
if qs.get("needs_key") != None:
    needs_key = qs["needs_key"][0]
else:
    needs_key = None

print "thread_id=", thread_id
print "user_id=", user_id
print "message_server=", message_server
print "message_path=", message_path
print "needs_key=", needs_key

# コメントのダウンロード
headers['Content-type'] = 'text/xml'
if needs_key == '1':
    conn = httplib.HTTPConnection('www.nicovideo.jp', 80)
    conn.request('GET', "/api/getthreadkey?thread=%s" % videoid, '', headers)
    rs = conn.getresponse()
    body = rs.read()
    rs.close()
    conn.close()
    getthreadkeySet = body.split('&')
    getthreadkeyArray = []
    for paramSet in getthreadkeySet:
        getthreadkeyArray.append(paramSet.split('='))
    xml = '<thread thread="%s" version="%s" res_from="%s" user_id="%s"' % (thread_id, 20061206, - 10, user_id)
    for paramSet in getthreadkeyArray:
        xml = xml + ' %s="%s"' % (paramSet[0], paramSet[1])
    xml = xml + '/>'
else:
    xml = '<thread thread="%s" version="%s" res_from="%s" user_id="%s"/>' % (thread_id, 20061206, - 10, user_id)
print 'xml=', xml
conn = httplib.HTTPConnection('%s.nicovideo.jp' % message_server, 80)
conn.request('POST', message_path, xml, headers)
rs = conn.getresponse()
body = rs.read()
rs.close()
conn.close()

# コメントを出力
print body


っというわけで・・・

ドン!ヽ(^∇^*)/


これで2期第12話も見れるぞ (|||ノ`□´)ノオオオォォォー!!

っと言う訳で、今回はこの辺でノシ