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

d:id:nkoz:20070606:1181063628をアップデート。

使い方

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

gem install hpricot
gem install mechanize

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

必要に応じてコメントアウトを外したり、書き換えたりして使ってください。

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

前回(d:id:nkoz:20070606:1181063628)との違い

  • エラー処理の追加
    • エラーが発生すると"error.log"にエラーメッセージが残ります。
  • ファイルのリネーム
  • 動画のタイトルを可能な限り拾ってきます。削除済の作品と思われるものには"(削除済)"とつくようになりました。
    • それでもタイトルが拾えなかったらリネームをあきらめます。
    • Windowsのファイル名で使えない文字は"_"で置き換えます。

nicobase.rb

require 'rubygems'
require 'hpricot'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'net/http'
require 'uri'
require 'cgi'
$KCODE = 'SJIS'

def geturl_using_nicovideo(mail,password,flv_id)
  begin
    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")
  rescue
    flv_link=""
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のurl取得に失敗。\n")
  end
  flv_link
end

def geturl_using_nicovideon(flv_id)
  begin
    agent = WWW::Mechanize.new
    nicovideon_page= agent.get("http://www.nicovideon.jp/watch/"+flv_id)
    flv_linkpage = nicovideon_page.links.text("↓ Download FLV.".toutf8)
    flv_link=flv_linkpage.href
  rescue
    flv_link=""
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のurl取得に失敗。\n")
  end
  flv_link
end

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

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

def download_using_nicovideo(mail,password,flv_id)
  success=download_flv(flv_id,geturl_using_nicovideo(mail,password,flv_id))
  errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のダウンロードに失敗。\n") if success==false
end

def download_using_nicovideon(flv_id)
  success=download_flv(flv_id,geturl_using_nicovideon(flv_id))
  errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のダウンロードに失敗。\n") if success==false
end

def download_using_nicopon(flv_id)
  success=download_flv(flv_id,geturl_using_nicopon(flv_id))
  errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のダウンロードに失敗。\n") if success==false
end

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

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

def gettitle_using_nicovideo(flv_id)
  begin
    nicovideo_page= Hpricot(open("http://www.nicovideo.jp/thumb?v="+flv_id))
    flv_title=(nicovideo_page/"table"/"p.TXT12"/"a").first.inner_html
  rescue
    flv_title=""
    begin
    nicovideo_page= Hpricot(open("http://www.nicovideo.jp/watch/"+flv_id))
    flv_title=(nicovideo_page/"h1").first.inner_html
    if utf8_to_sjis(flv_title)=="動画エラー" then
      errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のタイトル取得に失敗(動画エラー)。\n")
      flv_title=""
    else
      flv_title=sjis_to_utf8("(削除済)")+flv_title
    end
    rescue
      flv_title=""
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のタイトル取得に失敗。\n")
    end
  end
utf8_to_sjis(flv_title)
end

def gettitle_using_nicovideon(flv_id)
  begin
    nicovideon_page= Hpricot(open("http://www.nicovideon.jp/watch/"+flv_id))
    flv_title=(nicovideon_page/"h2").first.inner_html
    utf8_to_sjis(flv_title)
  rescue
    flv_title=""
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のタイトル取得に失敗。\n")
  end
  utf8_to_sjis(flv_title)
end

def flv_rename(flv_id,title)
  if title!="" then
    filename_before=flv_id+".flv"
    filename_after="["+flv_id+"]"+title+".flv"
    filename_after=filename_after.gsub(/[\\\/\,\;\:\*\?\"\<\>\|]/,'_')
    begin
      File.rename filename_before,filename_after
    rescue
      errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のファイル名書き換えに失敗。\nfilename_before: "+filename_before+"\nfilename_after: "+filename_after+"\n")
    end
  else
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"のファイル名書き換えは行いませんでした。\n")
  end
end

def flv_rename_using_nicovideo(flv_id)
  flv_rename(flv_id,gettitle_using_nicovideo(flv_id))
end

def flv_rename_using_nicovideon(flv_id)
  flv_rename(flv_id,gettitle_using_nicovideon(flv_id))
end

def getxml_using_nicovideo(mail,password,flv_id)
  begin
    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
    }
  rescue
    errorlog_output(Time.now.to_s+": ニコニコ動画 "+flv_id+"の字幕データ取得に失敗。\n")
  end
end

def errorlog_output(message)
  el = File.open("error.log",'a')
  el.puts message
  el.close
end

nicovideo1.rb

#c:\ruby\bin\ruby -Ks
require 'rubygems'
require 'hpricot'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'net/http'
require 'uri'
require 'cgi'
$KCODE = 'SJIS'

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'
require 'cgi'
$KCODE = 'SJIS'

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)