RubyとSeleniumを使って自動で画像をダウンロードする
2015/07/03
はじめに
ディープラーニング旋風に触発されて機械学習に興味をもった。
前々から機械学習やってみたいと思っていたのだが、SURF、HOGといった特徴量の抽出のあたりが職人芸らしい、という噂を聞いて『そんな根性ないわ。。』と諦めていたのだが、ディープラーニングは特徴量の抽出すら機械がやってくれると聞いて、『あ、これはやろう』となったのだ。
機械学習の中でも、自分は画像の識別に興味を持っている。
画像識別をやるなら既存のデータセットを使ってでも十分可能。
なのだが、椅子とか戦闘機を分類することにはあまり興味が湧かない。
となると自らデータセットを作る必要がある。
1枚1枚丁寧に画像を集めるのも良いが、たぶん終わる頃には死んでいるだろう。
じゃあスクリプト使って画像集めをやろう、そう思ったわけだ。
どこで画像を集めるか
bing.comで集めることにした。
Googleより品揃え豊富な印象があったので。
他に良さそうなサイトがあれば知りたいなあ。
どうやって集めるか
タイトル通りSeleniumを使ってやることにした。
Rubyのバインディングを使う。
bingはクローリング対策が結構されている感じで、jsを実行できるクローラーが必要だった。
普通のクローラーだとjsは実行できない(と、思ってる)はず。
なので、nodejsのnightmarejsを利用してヘッドレス系クローラー軽く実装してみたが、htmlが複雑なclass構造でnightmarejsでサクッとやれる感じがしなかった(技量不足)。
と、いうわけで。
より人間の動きっぽさを実装しやすいと、自分の中で有名なSelenuimを使ってブラウザを自動操作しつつ画像をダウンロードしてみた。
コード
こんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
require 'selenium-webdriver' require 'uri' require 'open-uri' def fetch_image_url_list(driver) image_layout_list = driver.find_elements(:class, 'dg_u') image_layout_list.collect { |image_layout| url = image_layout.find_element(:tag_name, 'img').attribute('src') if url =~ /\A#{URI::regexp(['http', 'https'])}\z/ url else nil end }.compact end def scroll(driver) driver.find_elements(:class, 'dg_u').last.location_once_scrolled_into_view sleep 2 end def fetch_image(url,file_name=nil,dir="images") if file_name.nil? file_name = File.basename(url) end save_image_name = dir + '/' + file_name + '.jpg' p save_image_name open(save_image_name, 'wb') do |file| open url do |data| file.write(data.read) end end end query = ARGV[0] if query.nil? p 'you need put a query.' exit end driver = Selenium::WebDriver.for :chrome driver.navigate.to 'http://bing.com/images/search?q=' + query driver.find_elements(:class, 'ftrLi').last.click sleep 2 safe_search = driver.find_element(:class, 'ftrBRF') .find_elements(:class, 'ftrLi').last tab = safe_search.find_element(:class, 'ftrTB') tab.click sleep 2 hidden_tab = safe_search.find_element(:class, 'ftrDC') safe_off = hidden_tab.find_elements(:tag_name, 'a').last safe_off.click sleep 2 scroll driver image_url_list = fetch_image_url_list(driver) image_url_list.each_with_index { |url, index| fetch_image url, query + index.to_s } driver.quit |
いちいちブラウザを立ち上げて処理をこなすようになっているため、よくあるクローラーと比較すると大分遅い。
機能ってほどでもないが、ちょい使えるようにした。
- クエリを引数に与えられるようにした
- ファイル名を自動でつけるようにした
- スクロールさせて取得する画像の量を増やした(scrollを呼べば呼ぶほど沢山の画像がダウンロードできる)
で、こんな感じで呼び出せばOK
1 |
ruby image_fetcher.rb 柴犬 |
アレ
banされない程度にやろう。
336px
336px
関連記事
-
-
プログラミング入門以前
これ …
-
-
scrapy実行時のエラー対処
Ma …
-
-
DockerでNginxしたい
Co …
-
-
Ruby,Railsのチートシート
こう …
-
-
ディープラーニングが気になる
ダラ …
-
-
フロントエンド開発のメモ
最近 …
-
-
Docker導入したらどうするの?
Do …