たれみみマンデー

Rubyで画像を無限に収集する

 

機械学習をするに大量の画像が必要だったのでプログラムをかきました。

個人的にGoogle画像検索よりBingの方が精度のいい画像がでてくると今回初めて気づいたのでBing画像検索でレッツゴーです。最新版のBing検索でRubyスクリプトはうちだけ!(なはず笑 探してもなかったからブログ書いてます)

(本来ならAPIを使うべきですが、Googleは制限が多い、BingはUIが変わってAPIが使えなかった、のでこのような対応をとりました。サーバー負荷を念頭に必ずおとなしくやりましょう。自己責任でお願いします。)

 

require 'selenium-webdriver'
require 'nokogiri'
require 'open-uri'
require 'date'
require 'addressable/uri'
require 'kconv'
require "uri"
require 'open_uri_redirections'

#文字対応増やすためStringクラスを拡張
class String  
  def sjisable  
   str = self  
   str = str.exchange("U+301C", "U+FF5E") # wave-dash  
   str = str.exchange("U+2212", "U+FF0D") # full-width minus  
   str = str.exchange("U+2013", "U+FF0D") # full-width minus  
   str = str.exchange("U+00A2", "U+FFE0") # cent as currency  
   str = str.exchange("U+00A3", "U+FFE1") # lb(pound) as currency  
   str = str.exchange("U+00AC", "U+FFE2") # not in boolean algebra  
   str = str.exchange("U+2014", "U+2015") # hyphen  
   str = str.exchange("U+2016", "U+2225") # double vertical lines  
 end  

 def exchange(before_str,after_str)  
  self.gsub( before_str.to_code.chr('UTF-8'),  
      after_str.to_code.chr('UTF-8') )  
 end  

 def to_code  
  return $1.to_i(16) if self =~ /U\+(\w+)/  
  raise ArgumentError, "Invalid argument: #{self}"  
 end  
end  



def get_url

driver = Selenium::WebDriver.for :chrome

#q=の後に日本語でキーワード入れて下さい(今は'安倍晋三'がエンコードされてます)
  driver.navigate.to 'https://www.bing.com/images/search?q=E6%A4%8E%E5%90%8D%E6%9E%97%E6%AA%8E'

   10.times do 
    driver.find_elements(:class, 'iusc').last.location_once_scrolled_into_view
      # Wait for the additional images to load
     current_count = driver.find_elements(:class, 'iusc').length
     until current_count < driver.find_elements(:class, 'iusc').length
      sleep(3)
     end
     sleep(5)
   end

  elements = driver.find_elements(:class, 'iusc')
# Check how many elements are there now
  ary = []
  elements.each do |element| 
       ary << element.attribute('m').scan(/","murl\":"(.+)","turl":/)
  end

  @ary = []
  ary.flatten!
  ary.each do |img|
    if /\.(jpg|png)$/ =~ img.to_s 
      @ary << URI.escape(img.to_s.force_encoding('utf-8').sjisable.encode('UTF-8'))
    end
  end
 @ary.flatten!
# ファイルの書き出しを行う
  @ary.each_with_index do |url,i|
# ファイル名を決定
    begin
# filename = File.basename(url)
     if /\.(jpg)$/ =~ url 
      filename = "abe#{i}.jpg"
     else 
      filename = "abe#{i}.png"
     end
# ファイルを保存するディレクトリ名を指定
   p filename
    dirname = "./abe_img/*" + filename
      open(dirname, 'wb') do |file|
        open(url.encode("utf-8", invalid: :replace, undef: :replace), :allow_redirections => :safe) do |data|
          sleep(1)
          file.write(data.read)
        end
      end
    rescue
      puts "とばしました"
    end
  end
end
get_url

エラーでたらそれはきっとsleniumドライバーのあれかBingの仕様変更です。

前者であればたくさんでてくるのでググってみて下さい笑

 

10.times do の数字をいじれば30件毎に画像の取得件数が増減すると思います(アレ、色がなんかおかしいぞまあいいや)

 

なにか質問等あれば気軽に連絡ください。

だれかのためになれば幸いです。

それでは〜!

 

たれみみ

@taremimi_7