ニコニコ動画の公式動画に投稿されたコメントの取得方法 (一部修正)
前回、公式動画のコメントを取得するために 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話も見れるぞ (|||ノ`□´)ノオオオォォォー!!
っと言う訳で、今回はこの辺でノシ