Pixivのタイトル、タグ検索から一定数以上のブックマークがある画像だけを保存するスクリプト
これは何?
- スクリプトがある場所に検索ワード名のディレクトリを作成します
- 最後のページまで保存対象となる画像(一定ブックマーク数以上)を保存し続けます
- 構成物
- pixiv.rb
- config.yaml
pixiv.rb
#! ruby -Ku require 'net/http' require 'uri' require 'yaml' require 'kconv' class AccessPixiv #InitializeでCookieを取得しHeaderも構築する #成功:Trueを返す #失敗:Falseを返す def initialize(pixiv_id, pixiv_pass, user_agent, referer) get_cookie(pixiv_id, pixiv_pass, user_agent, referer) end #uriで指定されたページ内容を取得する #成功:対象URIの内容を返す #失敗:Falseを返す def get_file(uri) sleep 3 * (rand(5) + 1) puts "get #{uri}" site = URI.parse(uri) begin Net::HTTP.start(site.host, 80) do |http| response = http.get(site.request_uri, @header) if disp_error(response) == true return response.body else return false end end rescue Errno::ETIMEDOUT, TimeoutError puts 'Timeout Error. Retry.' retry end end #word : 検索語 #s_mode: 検索モード #users : ユーザ数閾値 def search(word, s_mode, users) save_dir = make_dir(word) /検索結果:(\d+)件/ =~ get_file("http://www.pixiv.net/search.php?word=#{URI.encode(word)}&s_mode=#{s_mode}") start_p = 1 goal_p = $1.to_i / 20 + 1 puts "Total Images: #{$1}" puts "Total Pages : #{goal_p}" for p in start_p..goal_p page = get_file("http://www.pixiv.net/search.php?word=#{URI.encode(word)}&s_mode=#{s_mode}&p=#{p}") page.scan(/"(http:\/\/.+\.pixiv\.net\/img\/.+\/(\d+_s\..{3}))".+?\s.+?\s.+?(\d+) users/) do |uri, id, user| if user.to_i >= users uri.sub!(/_s/, ''); id.sub!(/_s/, '') if data = get_file(uri) save_file(data, "#{save_dir}/#{user}_#{id}") end end end end end #タグ検索 def search_tag(word, users) search(word, 's_tag', users) end #タイトル・キャプション検索 def search_title(word, users) search(word, 's_tc', users) end #ファイル保存 def save_file(data, filename) puts "save #{filename}" open(filename, 'wb') do |f| f.puts data end end #ディレクトリ作成 def make_dir(name) if /mswin(?!ce)|mingw|cygwin|bccwin/ =~ RUBY_PLATFORM.downcase save_dir = "./#{name.tosjis}" else save_dir = "./#{name}" end if File.exist?(save_dir) puts "Directory exist" else Dir.mkdir(save_dir) end return save_dir end private #Cookie取得 def get_cookie(pixiv_id, pixiv_pass, user_agent, referer) begin Net::HTTP.start('www.pixiv.net', 80) do |http| response = http.post('/index.php', "mode=login&pixiv_id=#{pixiv_id}&pass=#{pixiv_pass}", 'User-Agent' => user_agent ) if disp_error(response) == true cookie = response['Set-Cookie'].split(',') @header = { 'User-Agent' => user_agent, 'Referer' => referer, 'Cookie' => cookie[1] } return true else return false end end rescue Errno::ETIMEDOUT, TimeoutError puts 'Timeout Error. Retry.' retry end end #Error表示 def disp_error(response) case response when Net::HTTPBadRequest puts 'Error 400' when Net::HTTPUnauthorized puts 'Error 401' when Net::HTTPForbidden puts 'Error 403' when Net::HTTPNotFound puts 'Error 404' when Net::HTTPInternalServerError puts 'Error 500' when Net::HTTPServiceUnavailable puts 'Error 503' else return true end return false end end def example config = YAML::load_file(ARGV[0]) pixiv = AccessPixiv.new(config['pixiv']['id'], config['pixiv']['pass'], config['pixiv']['user_agent'], config['pixiv']['referer']) pixiv.search_tag(ARGV[1].toutf8, ARGV[2].to_i) end example()
config.yaml
pixiv: id : 'UserID' pass: 'PassWord' user_agent: 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)' referer: 'http://www.pixiv.net/mypage.php'
How to use
C:\pixiv>pixiv.rb config.yaml test 50
第1引数: 設定ファイル
第2引数: 検索ワード
第3引数: 保存対象とする画像のブックマークユーザ数(この例の場合、"users 50"以上の画像が対象となる)
Other
負荷対策としてSleepを長く入れてあります。
自分用に作ったものなので、使っていて気になった部分は直していきます。
Thanks
Search部分の着想は下記記事から得ました。
pixivのデータを拾ってくるRubyのコードを書きました - 下林明正の日記