今更だけどニコニコ動画をダウンロードするRubyスクリプト

RubyでHTMLとWebを操作するためのライブラリ、HpricotとWWW::Mechanizeのサンプルスクリプトに心動かされて、ニコニコ動画をダウンロードするスクリプトを書いてみた。

anond:20070506114948などを参考にさせていただきました。

Windows XP Pro SP2、One-Click Ruby Installer 1.8.6-25で動作確認。事前に

gem install hpricot
gem install mechanize

とやっておいてください。

flvファイルのダウンロードの処理はwgetにやらせています。あらかじめwgetをpathの通ったディレクトリにでもインストールしておいてください。

nicobase.rb

require 'rubygems'
require 'hpricot'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'net/http'
require 'uri'

def geturl_using_nicovideo(mail,password,flv_id)
agent = WWW::Mechanize.new
login_page = agent.get("http://www.nicovideo.jp/")
login_form = login_page.forms.first
login_form['mail'] = mail
login_form['password'] = password
redirect_page = agent.submit(login_form)
getflv = agent.get("http://www.nicovideo.jp/getflv?v="+flv_id)
getflv_url=URI.decode(getflv.body)
getflv_url2=getflv_url.split(/\s*&\s*/)
flv_link=getflv_url2[3].slice(4..getflv_url2[3].length)
logout=agent.get("http://www.nicovideo.jp/logout")
flv_link
end

def geturl_using_nicovideon(flv_id)
agent = WWW::Mechanize.new
nicovideon_page= agent.get("http://www.nicovideon.jp/watch/"+flv_id)
flv_link = nicovideon_page.links.text("↓ Download FLV.".toutf8)
flv_link.href
end

def geturl_using_nicopon(flv_id)
"http://nicopon.jp/video/src/"+flv_id
end

def download_flv(flv_id,flv_url)
p system("wget -O "+flv_id+".flv "+flv_url)
end

def download_using_nicovideo(mail,password,flv_id)
download_flv(flv_id,geturl_using_nicovideo(mail,password,flv_id))
end

def download_using_nicovideon(flv_id)
download_flv(flv_id,geturl_using_nicovideon(flv_id))
end

def download_using_nicopon(flv_id)
download_flv(flv_id,geturl_using_nicopon(flv_id))
end

def utf8_to_sjis(string)
Kconv.kconv(string,Kconv::SJIS,Kconv::UTF8)
end

def gettitle_using_nicovideo(flv_id)
nicovideo_page= Hpricot(open("http://www.nicovideo.jp/thumb?v="+flv_id))
flv_title=(nicovideo_page/"table"/"p.TXT12"/"a").first.inner_html
utf8_to_sjis(flv_title)
end

def gettitle_using_nicovideon(flv_id)
nicovideon_page= Hpricot(open("http://www.nicovideon.jp/watch/"+flv_id))
flv_title=(nicovideon_page/"h2").first.inner_html
utf8_to_sjis(flv_title)
end

def flv_rename_using_nicovideo(flv_id)
filename_before=flv_id+".flv"
filename_after="["+flv_id+"]"+gettitle_using_nicovideo(flv_id)+".flv"
File.rename filename_before,filename_after
end

def flv_rename_using_nicovideon(flv_id)
filename_before=flv_id+".flv"
filename_after="["+flv_id+"]"+gettitle_using_nicovideon(flv_id)+".flv"
File.rename filename_before,filename_after
end

def getxml_using_nicovideo(mail,password,flv_id)
agent = WWW::Mechanize.new
login_page = agent.get("http://www.nicovideo.jp/")
login_form = login_page.forms.first
login_form['mail'] = mail
login_form['password'] = password
redirect_page = agent.submit(login_form)
getflv_page = agent.get("http://www.nicovideo.jp/getflv?v="+flv_id)
getxml_id=URI.decode(getflv_page.body)
getxml_id2=getxml_id.split(/\s*&\s*/)
thread_id=getxml_id2[0].slice(10..getxml_id2[0].length)
xml_url=getxml_id2[5].slice(10..-6)
logout=agent.get("http://www.nicovideo.jp/logout")
Net::HTTP.version_1_2
Net::HTTP.start(xml_url, 80) {|http|
  response = http.post('/api/',
                       '<thread res_from="-500" version="20061206" thread="'+thread_id+'" />')
result=response.body
file_name=flv_id+".xml"
File.open file_name, 'w' do |f|
 f.write result
end
}
end

nicovideo1.rb

#c:\ruby\bin\ruby -Ks
require 'rubygems'
require 'hpricot'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'net/http'
require 'uri'
load 'nicobase.rb'

#いちいち聞かない場合
flv_id=ARGV[0]
if flv_id==nil then
puts "flv_id?(ex. sm9)"
flv_id=gets.chomp!
end

#必要に応じてコメントアウトを外す
#mail="(ニコニコに登録しているメールアドレス)"
#password="(ニコニコに登録しているパスワード)"

#いちいち聞く場合
#puts "mailaddress?"
#mail=gets.chomp!
#puts "password?"
#password=gets.chomp!
#puts "flv_id?(ex. sm9)"
#flv_id=gets.chomp!

#ダウンロードの処理
#どれか一つコメントアウトを外す。
#download_using_nicovideo(mail,password,flv_id)#ニコニコ動画を利用する場合(確実だが面倒)
#download_using_nicovideon(flv_id)#nicovideon.jpを利用する場合(不確実性が高い)
#download_using_nicopon(flv_id)#nicopon.jpを利用する場合(不確実性が高い)

#リネームするならどれか一つコメントアウトを外す。たまに失敗することもある。
#flv_rename_using_nicovideo(flv_id)
#flv_rename_using_nicovideon(flv_id)#nicovideon.jpを利用する(あまりおすすめしない)

#ニコニコ動画の字幕を拾う(試験版、あまりおすすめしない。flvと一緒に使うならリネームしない方が便利かも)
#getxml_using_nicovideo(mail,password,flv_id)

nicovideo2.rb

#c:\ruby\bin\ruby -Ks
require 'rubygems'
require 'hpricot'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'net/http'
require 'uri'
load 'nicobase.rb'

#必要に応じてコメントアウトを外す
#mail="(ニコニコに登録しているメールアドレス)"
#password="(ニコニコに登録しているパスワード)"
flv_id=""

def expansion_list(mail,password)
  $*.each do |files|
    File::open(files) do |file|
      file.each {|line| line.chomp!; flv_id=line; download_using_nicovideo(mail,password,flv_id); getxml_using_nicovideo(mail,password,flv_id)}
    end
  end
end

expansion_list(mail,password)

#ダウンロードの処理
#download_using_nicovideo(mail,password,flv_id)#ニコニコ動画を利用する場合(確実だが面倒)
#download_using_nicovideon(flv_id)#nicovideon.jpを利用する場合(不確実性が高い)
#download_using_nicopon(flv_id)#nicopon.jpを利用する場合(不確実性が高い)

#リネームするならどれか一つコメントアウトを外す。たまに失敗することもある。
#flv_rename_using_nicovideo(flv_id)
#flv_rename_using_nicovideon(flv_id)#nicovideon.jpを利用する(あまりおすすめしない)

#ニコニコ動画の字幕を拾う(試験版、あまりおすすめしない。flvと一緒に使うならリネームしない方が便利かも)
#getxml_using_nicovideo(mail,password,flv_id)

nicovideo1.rbの使い方

ruby nicovideo1.rb sm9

nicovideo2.rbの使い方

ruby nicovideo2.rb dl.txt
dl.txt
sm9
sm276682