はてブで人気のある動画を自動的にダウンロードするスクリプト書いた

はてブで人気のエロ動画を自動でダウンロードするツール “xxxdl” 開発しましたを読んで、windows版を使ってみたら動かなかったので自分で作ってみた。

> 改善しました

Windows上で動かせるものを作るのはめんどくさそうだったので、ちょっと勉強していたRubyの練習がてらRubyで書いてUbuntuで動かすことにした。

処理の流れとしては、

  1. はてブから動画サイトのURLを引っ張ってくる
  2. 動画サイトのURLに飛んで、動画ファイルのURLを何とかして見つけるor生成する
  3. ファイルに保存
となる.そんなに難しくはなかったけど,強いて言うなら動画ファイルのURLをソースから探す部分が難しかった.

require "./downloader.rb"
require "./hatebu_loader.rb"

thread_max = 5
max_count = 100

xloader = HatebuLoader.new
#xloader.setHamster #xHamsterの動画をダウンロードするときはコメントを外す

xthreads = []
count = 0
locker = Mutex::new

thread_max.times do
	xthreads << Thread.start do
		while count < max_count
			link = nil
			cnt = nil
			locker.synchronize do
				cnt = count
				link = xloader.getUrl(count)
				count += 1
			end
			dl = VideoDownloader.new
			begin
				dl.setUrl(link)
			rescue OpenURI::HTTPError => e
				p e
				puts"error"
			else
				#dl.dlFromHamster #xHamsterの動画をダウンロードするときはこっちを使う
				dl.dlFromXVideos
			end
			puts "#{cnt} is finished."
		end
	end
end

xthreads.each do |x|
	x.join
end

puts "finish"
require "open-uri"
require "nokogiri"

class HatebuLoader
	def initialize
		@url = "http://b.hatena.ne.jp/entrylist"
		@query ={"url"=>"http://www.xvideos.jp", "sort"=>"count"}
	end
	def getUrl(count)
		@query["of"] = count.to_s
		url = @url.clone
		@query.each do |key, value|
			if !url.include?('?')
				url << '?' << key << '=' << value
			else
				url << '&' << key << '=' << value
			end
		end
		doc = Nokogiri::HTML(open(url))
		entries = doc.css('.entry-link')
		#puts url
		return entries[0].attributes['href'].value
	end

	def setHamster
		@query["url"]="http://xhamster.com"
	end
end
require "open-uri"
require "nokogiri"

class VideoDownloader
	def setUrl(url)
		@url = url
		@doc =  Nokogiri::HTML(open(url))
		@html = @doc.to_s
		@title = @doc.title
		@title.gsub!("/", "-") if @title.include? "/"
		#puts "loaded #{url}"
	end

	def dlFromXVideos
		if !@html.include? "flv_url"
			puts "cannot find video #{@url}"
			return
		end
		pos1 = @html.index("flv_url") + 8
		pos2 = @html.index("&amp;", pos1)
		len = pos2 - pos1
		@downloadUrl = URI.decode(@html[pos1, len])
		@title = @doc.css('div#main > h2')[0].child.text.strip
		downLoad
	end

	def dlFromHamster
		if @doc.css('#playerSwf').empty?
			puts "cannot find video #{@url}"
			return
		end
		pos1 = @html.index("\'srv\'") + 8
		pos2 = @html.index("\'file\'", pos1) - 8
		len = pos2 - pos1
		srv = @html[pos1, len]
		pos1 = @html.index("\'file\'") + 9
		pos2 = @html.index(".flv", pos1) + 4
		len = pos2 - pos1
		file = "/flv2/key=" + @html[pos1, len]
		@downloadUrl = srv + file
		@title = @doc.css("div#playerBox > h2.gr").text.strip
		downLoad
	end

	def downLoad
		fileName = "dl/" + @title + ".flv"
		if File.exist?(fileName)
			puts "#{@title}.flv is already downloaded"
			return
		end
		puts "downloading #{@title} #{@url}"
		File.open(fileName, 'wb') do |output|
			begin
				open(@downloadUrl) do |data|
					output.write(data.read)
				end
			rescue OpenURI::HTTPError
				File.open("error.log", 'a') do |f|
					f.puts "HTTPError, cannot download #{@title}, #{@url}\n#{@downloadUrl}"
				end
			end
		end
	end
end

GitHubに置いといたのでご自由にどうぞ。
マルチスレッドで動くんですが、排他制御が微妙で、設定したmax_countを多少ぶち抜いてしまったりします。直さなければ…