ニコニコ動画の新着投稿動画をチェックし続けるRubyスクリプト

ニコニコ動画にアップされた最新の動画は新着投稿動画(http://www.nicovideo.jp/newarrival)でチェックできるわけだけど、自分で常にチェックするのは面倒だし、しかし目当ての動画がアップされたら諸事情で早急に見たい、ということがあるかと思います。
ということで、1分毎に目当ての新着投稿動画を動画タイトルをもとにチェックし、見つけたらコマンドライン上で知らせるRubyスクリプトを書いた。
3/5 2:00追記: ログイン不要なものをこちらに書きました。また新着投稿動画は10分毎に更新のようなので頻繁にアクセスする必要はまったくありませんでした。

mechanizeを入れていない場合は、gem install mechanize で。


nico_newarrival.rb

require 'rubygems'
require 'mechanize'
require 'open-uri'
require 'kconv'
require 'date'

class NicoNewarrival

  def initialize
    @agent = WWW::Mechanize.new
    @agent.user_agent_alias = 'Mac Safari'
    login_page = @agent.get('http://www.nicovideo.jp/').forms[0]
    login_page['mail'] = 'hoge@foo.com' #ここに自分のメールアドレスを入力
    login_page['password'] = 'password' #ここにパスワードを入力
    @agent.submit(login_page)
    @agent
  end

  def check_newarrival
    str = []
  #コマンドラインで指定したファイルを読み込む
    f = open(ARGV[0], "r")
    while l = f.gets do
      str << l.chomp.toutf8
    end
    #新着投稿動画をチェックし続ける
    while true do
      targets = []
      newarrival = @agent.get('http://www.nicovideo.jp/newarrival')
      (newarrival/"/html/body/div[3]/div/table[2]/tr").each do |r|
        (r/:td).each do |d|
          title = (d/"/div/div[2]/p/a").inner_text
          sm = (d/"/div/div[2]/p/a")[0].attributes['href'].match(/\d+/).to_s
          str.each do |s|
            if Regexp.new(s) =~ title
              doc = Hpricot(open("http://www.nicovideo.jp/api/getthumbinfo/sm#{sm}"))
              if (doc/:nicovideo_thumb_response)[0].attributes['status'] == "ok"
                status = "ok"
                first_retrieve = DateTime.strptime((doc/:first_retrieve).inner_text)
                length = (doc/:length).inner_text
                view_counter = (doc/:view_counter).inner_text
                comment_num = (doc/:comment_num).inner_text
              else
                status = "fail"
                first_retrieve = nil
                length = nil
                view_counter = nil
                comment_num = nil
              end
              targets << [sm, status, title, first_retrieve, length, view_counter, comment_num]
            end
          end
        end
      end
      #目的の動画が見つかったら表示
      if !targets.empty?
        targets.each do |t|
          if t[1] == "ok"
            puts("#{t[2]}\n
                 #{t[3].strftime("%m/%d %H:%M:%S")}  length: #{t[4]}   view: #{t[5]}   comment: #{t[6]}\n
                 http://www.nicovideo.jp/watch/sm#{t[0]}\n")
          else
            puts("#{t[2]} deleted!")
          end
          puts "\n"
        end
      puts "**************************************************************************"
      end
      sleep 60
    end
  end

end

if __FILE__ == $0
  NicoNewarrival.new.check_newarrival
end

Windowsコマンドプロンプトsjisしか表示できないので、タイトルを表示する際に文字コードの変換が必要。具体的にはタイトルを表示している2カ所を下のようにしておくことに注意。

puts("#{t[2].tosjis} ......)

使い方はまず適当なテキストファイルに、目当ての動画のタイトルの一部分など以下のように書く。

nicotitles.txt


(ス|す).*(マ|ま).*(ブ|ぶ).*(ラ|ら)

改行で区切る。正規表現が使えるので上みたいに書けば多少の表記揺れなどは吸収できるのがポイント。

ruby nico_newarrival.rb nicotitles.txt

のように引数に目当てのタイトルを書いたテキストファイルを指定して実行する。


自分のidとパスワードに変更するのを忘れずに。
あとニコニコ動画の認証の性質上、同一アカウントで複数の場所からログインができないので、このスクリプトを走らせつつニコニコ動画を見る人はもう一つ別のアカウントがあったほうが便利です。



これを実行するとCtrl-cなどでプログラムを強制的に止めるまで、下のような画面が延々と続く。


まだ十分にテストとかしていないのでバグとかもあると思いますが、見つけしだい修正したいと思います。