Edited at

Rubyとnet/httpsライブラリを使用してニコニコ動画にログインする

More than 5 years have passed since last update.

前の投稿で試してみたニコニコ動画のgetthumbinfo APIはログインを必要としませんでした。しかし、参考ページによると他のAPIはログインが必要とのことです。

というわけで、Ruby 2.0.0とnet/httpsライブラリでニコニコ動画にログインするコードを書いてみました(というか、{このコードわからん}で公開されている綺麗なコードを練習用に汚くしてしまった感じです。できたら参考にさせて頂いたページでお口直しを)。

最初にコードを示します。

require 'net/https'

module NicovideoAPIWrapper extend self
def login(mail, password)
#ログインを試みる
https = Net::HTTP.new('secure.nicovideo.jp', 443)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = https.start{|https|
https.post('/secure/login?site=niconico', "mail=#{mail}&password=#{password}")
}

#set-cookieには複数のcookieが設定されている。
#user_sessionがdeletedでない最初のcookieを探す。
user_session = nil
response.get_fields('set-cookie').each {|cookie|
cookie.split('; ').each {|param|
pair = param.split('=')
if pair[0] == 'user_session' then
user_session = pair[1] if pair[1] != 'deleted'
break
end
}
break unless user_session.nil?
}
return user_session
end
end


test.rb

user_session = NicovideoAPIWrapper::login('<ニコニコ動画の登録メールアドレス>', '<ニコニコ動画のパスワード>')

puts "有効なセッションID:#{!user_session.nil? ? user_session : '<None>'}"

全体としてはHTTPSでPOSTしてset-cookieを受け取り、そこからログインが必要なAPIで使う有効なuser_sessionを取り出しています(詳しくは下の方で)。

NicovideoAPIWrapper::loginの前半、net/httpsでログインページにPOSTしてcookieを取得するまではnet/httpsのドキュメントにあるサンプルコードとほぼ一緒です。もちろん同期処理とかしていないので実行すると一時停止します。後半のコードはcookieをごたごた扱っています。実際には参考にさせて頂いたページの様にsplitで切り分けてindexした方が早いと思います。

これでログインが必要なニコニコ動画のAPIも使えるはずです。ちょこちょこと追加していけたら嬉しいです。ちなみに参考にしたページと同じで依存関係は最低限にしたいのでnet/httpsを使いましたが、他にも公開ライブラリを使用したログイン方法がいくつもあるそうです。検索すればすぐに見付かると思います。


ログインページから返されるset-cookieの内容

ニコニコ動画のログインページにメールアドレスとパスワードをPOSTした時、get_fields('set-cookie')はcookieの配列を返しますが、そこにはuser_session=deletedの無効なuser_sessionが複数含まれます。具体的には以下の通りです(hogeとかfugaは誤魔化し部分です)。

require 'net/https'

require 'pp'

mail = '<ニコニコ動画の登録メールアドレス'
password = '<ニコニコ動画のパスワード>'

https = Net::HTTP.new('secure.nicovideo.jp', 443)
https.use_ssl = true
https.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = https.start{|https|
https.post('/secure/login?site=niconico', "mail=#{mail}&password=#{password}")
}
pp response.get_fields('set-cookie')

=> ["nicosid=hoge.hoge; expires=Wed, 27-Dec-2023 09:50:19 GMT; path=/; domain=.nicovideo.jp",

"user_session=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT",
"user_session=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/",
"user_session=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.nicovideo.jp",
"user_session=fuga; expires=Tue, 28-Jan-2014 09:50:20 GMT; path=/; domain=.nicovideo.jp",
"repair_history=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; path=/; domain=.nicovideo.jp"]