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