ニコニコ動画へのリンクを抽出して flv ファイルを自動取得するクローラ

登録したサイトから、ニコニコ動画へのリンクを抽出して flv ファイルを取得するクローラ(?)を作ってみました。これと組み合わせると、

  • エコノミー時間帯に帰宅して通常画質で視聴
  • 削除された動画を視聴

とかできて便利じゃないかと思われます。

ソース

#!/usr/bin/ruby -Ku
require 'open-uri'
require 'kconv'
require 'yaml'
require 'rubygems'
require 'hpricot'
require 'nicovideo'

module Nicovideo
  class VideoPage
    def low?
      @params ||= get_params
      return true if CGI.unescape(@params['url']) =~ /low$/
      return false
    end
  end
end

def nico_save(s_id, mail, pass, dir="./")
  nv = Nicovideo.new(mail, pass)
  s_id.each do |id|
    skip = false
    f_name = nil
    f_path = nil
    begin
      next if skip
      nv.watch(id) do |v|
        f_name = "#{v.id}.flv"
        f_path = File.join(dir, f_name)
        unless File.exist?(f_path)
          File.open(f_path, "wb"){|f| f.write(v.flv) } unless v.low?
        end
      end
    rescue Timeout::Error
      warn "ERROR: #{f_name}"
      warn $!
      File.delete(f_path) if File.exist?(f_path)
      skip = true
      retry
    rescue
      warn "ERROR: #{f_name}"
      warn $!
      File.delete(f_path) if File.exist?(f_path)
      skip = true
      retry
    end
    sleep 1
  end
end

conf = YAML.load(open("conf.yaml") )
conf['url'].each do |u|
  sm_ids = []
  doc = Hpricot(open(u).read )
  filter = %r|^http://www\.nicovideo\.jp/watch/(sm\d*)$|
  (doc/:a).each{|link| sm_ids.push($1) if link[:href] =~ filter}

  nico_save(sm_ids, conf['mail'], conf['password'], conf['save_dir'])
end

設定ファイル

スクリプトと同一のディレクトリに設定ファイル(conf.yaml)を置く必要があります。
以下の内容。

# ニコニコ動画アカウント
mail: メールアドレス
password: パスワード

# 保存場所
save_dir: ./flv/

# 取得対象URL
url:
 - http://www.mew5.com/
 - http://www.geocities.co.jp/HeartLand-Hanamizuki/9167/
 - http://sky.geocities.jp/vocaloid_original/mikuori/mo_top.html

必要なパッケージ

HTML解析にhpricot、flvダウンロードにnicovideo を利用しているのでgemで導入してください。

% sudo gem install hpricot
% sudo gem install nicovideo

あとはcronに登録すればOK。
エコノミーモードの動画は取得しません。その為に、VideoPageを拡張しました。あとは、Timeout::Errorのrescue節が冗長な感じ。どうやってキャッチするのが適切なんでしょう。