ニコニコ生放送情報取得
ニコ生アラート(本家)の仕様とは (ニコナマアラートホンケノシヨウとは) [単語記事] - ニコニコ大百科 に情報がまとめられてる。 XMLRequest とかいうよくわからんことを要求されたが、pythonでXMLSocket - たいしょー(miettal)の日記 をみつつ適当に書いたら動いた(適当)。以下コード
#!/usr/bin/env ruby require "net/http" require 'uri' require 'pp' require "rexml/document" require 'socket' require 'pry' def login_free() uri = URI.parse('http://live.nicovideo.jp/api/getalertinfo') res = Net::HTTP.start(uri.host, uri.port) {|http| http.get( uri.path ) } xml = REXML::Document.new(res.body) raise "returned status: not ok" unless xml.elements["getalertstatus"].attribute("status").value == "ok" addr = xml.elements["getalertstatus/ms/addr"].text port = xml.elements["getalertstatus/ms/port"].text thread = xml.elements["getalertstatus/ms/thread"].text return addr,port,thread end def login(mail, password) uri1 = URI.parse('https://secure.nicovideo.jp') https = Net::HTTP.new(uri1.host, uri1.port ) https.use_ssl = true res = https.start {|http| http.post( "/secure/login?site=nicolive_antenna" ,"mail=#{mail}&password=#{password}") } raise "login err" unless res.code == "200" xml = REXML::Document.new(res.body) resp = xml.elements["nicovideo_user_response"] raise "unexpected responce" unless resp.attribute("status").value == "ok" ticket = resp.elements["ticket"].text puts "ticket=#{ticket}" uri2 = URI.parse('http://live.nicovideo.jp/api/getalertstatus') res = Net::HTTP.start(uri2.host, uri2.port) {|http| http.get( uri2.path + "?" + "ticket=#{ticket}") } xml = xml = REXML::Document.new(res.body) raise "returned status: not ok" unless xml.elements["getalertstatus"].attribute("status").value == "ok" puts "communities = " ,xml.get_elements("getalertstatus/communities/community_id").map {|e| e.text}.join(";") puts "user_id = ", xml.elements["getalertstatus/user_id"].text puts "user_name = ", xml.elements["getalertstatus/user_name"].text addr = xml.elements["getalertstatus/ms/addr"].text port = xml.elements["getalertstatus/ms/port"].text thread = xml.elements["getalertstatus/ms/thread"].text return addr,port,thread end addr, port, thread = login(ARGV[0],ARGV[1]) p addr,port,thread s = TCPSocket.open(addr, port) s.write("<thread thread=\"#{thread}\" version=\"20061206\" res_from=\"-1\"/>") s.write(0.chr) r = "" while true r += s.recv(100000).to_s while i = r.index( 0.chr ) thread = r[0, i] r = r[i+1, (r.size() -1)] # if i+1 == r.size, then r would be "" puts thread puts "" end #sleep 1 end
これ、ログインしてからコメントサーバに接続しても、すべての放送が push されるわけだけど、それは良いのかな。 server 側は一回 push して各クライアントが勝手にもらってく、って形だから大丈夫っぽい?(情弱)。
ニコ生アラート(偽)をつくるなら、参加コミュニティをまず取得しておいて、すべての新着放送から該当する放送のみをフィルタリングする感じだと思う。
それともうひとつ、mechanize で マイページにアクセス、リダイレクトされるのでログイン、再びアクセス、の流れ。本当は web-client(mechanize)使わずに net/http だけでやりたかった。しかしニコニコ動画はログイン管理に cookie 使っているらしくて、その cookie の扱いが ローレベルの net/http だけでやろうとすると、 cookie の仕様やら何やらも考慮する必要があってよくわからなくなってしまった。結果、妥協して mechanize を使った。
# -*- coding: utf-8 -*- require 'mechanize' require 'uri' require 'pry' agent = Mechanize.new agent.user_agent = 'Mozilla/7.0' top = URI.parse 'http://www.nicovideo.jp/my/top' agent.redirect_ok = false r = agent.get(top) raise "err" unless r.code =~ /30[12]/ login_page = r.header["location"] r = agent.get(login_page) #agent.verify_mode = OpenSSL::SSL::VERIFY_NONE next_page = r.form_with(:id => 'login_form') do |form| raise "no such form" if form.nil? form.mail_tel = ARGV[0] form.password = ARGV[1] end.submit p next_page.code, next_page.uri, next_page.header["location"] #> loc = /my/top r = agent.get(top) p r.at("html/body").text File.open("tmp.html", "w") {|f| f.write( r.body ) }
ニコニコ動画ログイン, cookie & session with ruby
Rubyとnet/httpsライブラリを使用してニコニコ動画にログインする - Qiita
2007-02-16 - みずぴー日記
How to implement cookie support in ruby net/http? - Stack Overflow
Cookieとセッションをちゃんと理解する - Qiita <- ちゃんと読んでない
WebサーバーからWebブラウザへHTTPレスポンスのヘッダを利用して小さな情報を送る。 この情報は「名前=値」の組み合わせで表される。
Webアプリケーション側では、リクエスト•ヘッダに入っているCookieを調べることで、アクセスしてきた相手がどのような相手なのかを知ることができる
Cookieは、サーバアクセスするたびに自動送信される http://www.htmq.com/webstorage/
Cookieを受け取ったあとでも、Cookieを受け取ったサーバとは異なるWebサーバに対しては>Cookieを送らない。(意図しない情報がほかのWebサーバーに送られるのを防ぐ) https://secure.php.net/manual/ja/features.cookies.php
cookie は 同じ名前のを遅れたり expire を設定したりと自力でやるのはつらい。というか、それ自力でつくたっら、ブラウザのサブセットを作っていることになって無為。 Rubyのnet/httpでGoogleにログイン - 瓶詰堂日記
mechanize, 自動化
Mechanize について - 君の瞳はまるでルビー - Ruby 関連まとめサイト
楽々スクレイピング! Ruby Mechanizeの使い方 -- ぺけみさお
Mechanize::Form - Ruby Mechanize wiki (ja)
Mechanizeの使い方(CookiesはRedisサーバへ保存) - 別館 子子子子子子(ねこのここねこ) <- pry で ls <obj>
するとメソッド列挙してくれるのはじめって知ったけど、めちゃ便利そう
Webブラウザの自動操作 (Selenium with Rubyの実例集) - Qoosky
まとめ
時間だけかけて結局何もしてないやつやめたい