ニコニコ動画をRubyスクリプトで操作(+Firefoxとのセッション共有)

ニコニコ動画Rubyで操作する方法として、nicovideo という直球な名前の使いやすいgemがあるのを知った。使い方はとても簡単。普通に gem install nicovideo でインストールして、たとえばデイリーランキングのTSV出力であれば

require 'rubygems'
require 'nicovideo'

nico = Nicovideo.new('メールアドレス', 'パスワード')
nico.ranking.each_with_index do |vp, i|
  puts [i+1, vp.video_id, vp.title].join("\t")
end

これだけ。(ちなみに規約をみるとダウンロードは違反っぽいので自重)

ただ、これだと別ブラウザでの再ログイン扱いになるため、普通のブラウザで見る場合は再度ログインしないといけない。これは面倒なので、Firefox 3のセッションを共有してみる(ほかのブラウザでも、永続化されてる Cookie のはずなので似たようなことはできると思う)。

RubyのMechanizeのMozillaクッキー読み込み機能が重いので迂回する on Firefox3
を参考にさせていただきました。

こんな感じ。あらかじめ gem install sqlite3-ruby しておいて、

require 'rubygems'
require 'nicovideo'
require 'sqlite3'

# Macなら、こんな感じの場所に Firefox の cookie データが入っている
# 参照先記事にもある通り、自動でもとれるけど面倒なので手抜き
dbf = '/Users/ユーザ名/Library/Application Support/Firefox/Profiles/プロファイルID.default/cookies.sqlite'

# name の絞り込みは適当。user_session だけあればいい?
sql = << 'SQL'
SELECT host, isHttpOnly, path, isSecure, expiry, name, value
FROM moz_cookies
WHERE host = '.nicovideo.jp'
  AND name not like '\_\_%' escape '\'
SQL

# このへん丸パクリ(すみません)
cookie = String.new
p = Proc.new{|s| s.to_i.zero? ? 'TRUE' : 'FALSE'}
db = SQLite3::Database.new(dbf)
db.execute(sql) do |r|
  cookie << [r[0], p.call(r[1]), r[2], p.call(r[3]), r[4], r[5], r[6]].join("\t") << "\n"
end

# ログインはしないので、Nicovideo::Base を直接指定して auto_login を false に
nico = Nicovideo::Base.new(nil, nil, false)

# 内部で使っている WWW::Mechanize に cookie をセット
nico.agent.cookie_jar.load_cookiestxt(StringIO.new(cookie))

# 以下前と同じように操作

うまくいくことを確認したら、お好みで前と同じように Nicovideo.new('メールアドレス', 'パスワード') に戻せば、「有効なCookieが取れればそのセッションを使い、取れなければ指定したアカウントで自動ログイン」という動作にもできる。