[ruby] 続ruby with mechanizeでニコニコ動画のダウンローダーを作ってみた
id:hsur にコメントでバグを指摘されたのでちょっと修正。
require 'yaml' require 'rubygems' require 'mechanize' require 'uri' require 'tempfile' class NicoVideo attr_reader :email, :password AGENT_ALIAS = 'Windows Mozilla' def initialize(*args) case args.length when 1 fname = args[0] raise unless File.exists?(fname) YAML.load_file(fname).each do |sym, value| instance_variable_set('@' + sym, value) end end @agent = WWW::Mechanize.new @agent.user_agent_alias = AGENT_ALIAS end def login if @agent.post("https://secure.nicovideo.jp/secure/login?site=niconico", {'mail' => @email, 'password' => @password}).header['x-niconico-authflag'] == '1' @login = true else raise LOGIN_FAILURE end end def login? @login end def get_flv(id) api = { } login unless login? URI.decode(@agent.get("http://www.nicovideo.jp/api/getflv?v=" + id).body).split('&').each do |query| query =~ /^([^=]+)=(.+)/ api[$1.to_sym] = $2 end raise VIDEO_NOT_FOUND unless api[:url] @agent.get("http://www.nicovideo.jp/watch/#{id}") dir = "/tmp/nicovideo" Dir.mkdir dir unless File.exists?(dir) path = "#{dir}/#{id}.flv" File.open(path, 'w') do |f| f.write @agent.get(api[:url]).body end unless File.exists?(path) Video.new(path) end class VIDEO_NOT_FOUND < StandardError; end class LOGIN_FAILURE < StandardError; end class Video attr_reader :tmpfile def initialize(path) @tmpfile = path end end end if $0 == __FILE__ NicoVideo.new(File.expand_path(File.dirname(__FILE__) + '/account.yml')).get_flv(ARGV[0]) end