インストール
パッケージは、sora_hの物を使うことにした。
gem install niconico
ドキュメントには書いてないけど、ruby1.9でしか動かない。1.9が好きになれない僕には、ちょっと不満。
ダウンロードする。
require 'niconico' nico = Niconico.new('takuya@example.com','*****') #ログインメアド、パスワード nico.login $stdout = open("out.flv", "w") puts nico.video("sm12345456").get_video $stdout.flush
一覧を取り込む
初音ミクなどのボカロランキングをまとめてダウンロードする。
これはMechanizeでさくっと。
require 'mechanize' nico = Niconico.new('takuya@example.com','*****') nico.login url = "http://www5.atwiki.jp/hmiku/pages/4386.html" m = Mechanize.new m.get url list = m.page.iframes.map{|e| e.src}.map{|e| e =~ /\/(sm[0-9]+)$/ ; $1} list.each{|e| video= nico.video(e) open("#{e}.flv", "w"){|f| f.write video.get_video } }
これで一括ダウンロード。もちろんシングルスレッドで動作させる。マルチスレッドだとダウンロードは出来ない。ニコニコ動画は複数スレッドでつなぐと応答してくれないからね。。。
一応マルチスレッド版もある
#!/usr/bin/env ruby #--coding: utf-8 require 'niconico' # ruby 1.9限定 require 'openssl' OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE Thread.abort_on_exception=true class Niconico class Downloader require 'thread' def initialize(address,pass) @address,@pass = address, pass @q = Queue.new @client = Niconico.new(@address,@pass) @client.agent.max_history=1 @client.login end def add_download_list(sm_id) @q.push sm_id end def worker t = Thread.new{ begin sm_id = nil retry_cnt = 1 loop{ sm_id = @q.pop video = @client.video sm_id open("nicovideo2/#{video.title.gsub(/\//,'\/')}.#{video.type}", "w"){|f| f.write video.get_video} break if @q.empty? sleep 10 } rescue => e @q.push sm_id unless e.inspect =~ /not found/ puts e retry_cnt = retry_cnt + 1 sleep 10*retry_cnt @client.login retry end } return t end def start_download (0..9).map{|i| t = self.worker;sleep 10*i;t } end end end
マルチスレッドで
require 'mechanize' downloader = Niconico::Downloader.new "takuyaXXXXXX**@gmail.com", "**password**" url = "http://www5.atwiki.jp/hmiku/pages/4386.html" m = Mechanize.new m.get url m.max_history = 2 list = m.page.iframes.map{|e| e.src}.map{|e| e =~ /\/(sm[0-9]+)$/ ; $1} list.each{|e| downloader.add_download_list e } threads = downloader.start_download threads.map{|t| t.join} puts :end
マルチスレッド版だから速いというわけ無く、単にマチスレッドを使って、ビデオIDをPostしたら待ちキューに入ってワーカーが淡々とダウンロードを繰り返す。これをつかって、drubyマチスレッドをポート指定で待ち受けてたり。