RubyでWebクローラっぽいのを作ってみたいと思った 続き
リダイレクトに対応したダウンロードプログラム
画像をダウンロードをするプログラムを作りました。レスポンスデータから抽出しただけのURLだとリダイレクトされる可能性があるのでそういう対応をしました。というかruby リファレンスにあるままです。
====
リダイレクトとは
ウェブサイトにおけるリダイレクト(英:redirect)とは、ウェブサイトの閲覧において、指定したウェブページから自動的に他のウェブページに転送されること。URLリダイレクト(URL redirection)とも言われる。
通常はウェブページのURLが変わったときに、元のURLから新しいURLへ誘導するときに用いられる。フィッシング詐欺サイトへの誘導などで用いられている場合もある
(by wikipedia)
ということです。
リダイレクトの例
以下のニュー速のページに画像ファイルがあります。
【2ch】ニュー速クオリティ:小学生の水着DVDに偶然映り込んだ山中知恵ちゃんのビキニが凄いことになってる
"ページのソースを表示"をすると
"<img src="http://livedoor.blogimg.jp/news4vip2/imgs/9/6/96a36e43.jpg" "
となっているところをクリックすると、画像が表示されるけど、そのURLは
"http://livedoor.4.blogimg.jp/news4vip2/imgs/9/6/96a36e43.jpg"
となっています。
よく見てみると、
- "http://livedoor.blogimg.jp.news4vip2/imgs/9/6/96a36e43.jpg"
- "http://livedoor.4.blogimg.jp/news4vip2/imgs/9/6/96a36e43.jpg"
微妙に違う!
つまりはリダイレクトなんです。そうなんです。
Rubyのプログラム
responseを見て処理をわけるようです。"Net::HTTPRedirection"がきた場合"response['location']"を見てリダイレクトされるURLへもう一度アクセスする仕組みです。"when"を増やせばほかのレスポンスにも対応できるねぇ。今はしないけど。
=begin ファイルをダウンロードするプログラム。リダイレクト対応 =end require 'net/http' require 'uri' def fetch(uri_str, save_path, limit = 10) # You should choose better exception. raise ArgumentError, 'HTTP redirect too deep' if limit == 0 response = Net::HTTP.get_response(URI.parse(uri_str)) case response when Net::HTTPSuccess puts response, " download..." size = response["Content-Length"].to_f File.open(save_path, "wb") do |file| file.write response.body end when Net::HTTPRedirection puts response, " Redirect..." fetch(response['location'], save_path, limit - 1) else puts response.value end end if __FILE__ == $0 fetch('http://livedoor.blogimg.jp/news4vip2/imgs/9/6/96a36e43.jpg', './image/foo.jpg') end
"download.rb"という名前です。