Ruby で画像収集

Rubyで画像収集ソフト的な物を作ってみた - チラシ裏日記上等!!を見て
面白そうだなぁと思い僕なりに少し書き換えてみた。


以下のスクリプトはまだ書きかけというか挙動があやしいのだけど
とりあえず貼り付けておく。
最後の画像保存するところ (save_image_file) でなんか止まるんだよなぁ (´▽`;)
どうして止まっちゃうのかよく分からない。。

require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'kconv'
require 'pp'

def save_image_file(url, path)
  puts url
  puts path
  open(path, 'wb') do |file|
    open(url) do |data|
      file.write(data.read)
    end
  end
end

urls = [
  "http://www.f8.dion.ne.jp/~zsilver/",
  "http://5-y.2-d.jp/",
  "http://www15.wind.ne.jp/~jekyll-and-hyde/",
]
urls = ["http://d.hatena.ne.jp/gan2/"]
#urls = ["http://www.f8.dion.ne.jp/~zsilver/"]

urls.each do |url|
  imgurls = []
  doc = Hpricot(open(url).read)
  title = (doc/:title).inner_html.tosjis

  puts title
  Dir.mkdir(title) unless File.exist?(title)

  (doc/:img).each do |img|
    imgurl = img.attributes["src"]
    imgurl = URI.join(url, imgurl).to_s unless %r{^http://([^/]+)} =~ imgurl
    imgurls << imgurl if /\.(bmp|gif|png|jpg)$/ =~ imgurl
  end
  pp imgurls
  
  imgurls.each do |imgurl|
    savepath = File.join(title, File.basename(imgurl))
    save_image_file(imgurl, savepath)
  end
end


ちなみに画像保存する処理は "net-http" を使わずに "open-uri" でやる方法に変えました。
"net-http" でも "open-uri" でも処理が止まっちゃうのは一緒だったので
save_image_file の呼び出し方がまずいのかも。


そういえば、いつからかはよく分からないけど
URI モジュールはいつのまにか「require 'uri'」しなくても使えるようになったんだなぁ。

追記

ちゃんと動くように改良した。
save_image_file は保存に成功したときは true を
保存に失敗したときは rescue して false を返すようにした。
これで一部の保存に失敗してもプログラムが途中で終了することがなくなった。


save_image_file の呼び出し元では

save_image_file(image_url, savepath) ? true : error_urls << image_url

などとすることで保存に失敗した URL を error_urls にまとめられる。

require 'rubygems'
require 'hpricot'
require 'open-uri'
require 'kconv'
require 'pp'
$stdout.sync = true

def save_image_file(url, path)
  puts url
  puts path
  open(path, 'wb') do |file|
    open(url) do |data|
      file.write(data.read)
    end rescue return false
  end
  true
end

base_urls = [
  "http://www.f8.dion.ne.jp/~zsilver/",
  "http://5-y.2-d.jp/",
  "http://www15.wind.ne.jp/~jekyll-and-hyde/",
]

base_urls.each do |base_url|
  image_urls = []
  error_urls = []
  doc = Hpricot(open(base_url).read)
  title = (doc/:title).inner_html.tosjis

  puts title
  Dir.mkdir(title) unless File.exist?(title)

  (doc/:img).each do |img|
    image_url = img[:src]
    image_url = URI.join(base_url, image_url).to_s unless %r{^http://([^/]+)} =~ image_url
    image_urls << image_url if /\.(bmp|gif|png|jpg)$/ =~ image_url
  end

  image_urls.each do |image_url|
    savepath = File.join(title, File.basename(image_url))
    save_image_file(image_url, savepath) ? true : error_urls << image_url
  end
end