スクレイピング対象のページが基本的に変更されることのない場合(近デジとか),キャッシュを作っておくと,毎回リクエストを投げずに済んで便利.
GETしか使わないときは簡単にキャッシュできる.
必ずUtil::fetch_uriというメソッドで通信するようにしておいて,
module Util def self.fetch_uri(uri) uri = URI.parse(uri) unless uri.kind_of? URI uri.read end end
spec_helperとかでメソッドを上書きして,キャッシュがあればそっちを使うようにする.
module Util def self.fetch_uri(uri) uri = URI.parse(uri) unless uri.kind_of? URI cache_directory = File.join(File.dirname(__FILE__), '..', 'spec', 'cache') Dir.mkdir(cache_directory) unless File.directory?(cache_directory) cache_file = File.join(cache_directory, Digest::SHA1.hexdigest(uri.to_s)) unless File.exists? cache_file open(cache_file, 'w') {|f| f.puts Marshal.dump(uri.read) } end Marshal.load open(cache_file).read end end
open-uriとURI#readの返り値は拡張されていて,base_uriとかが取れるようになってる.
openするとStringIOが来るのでMarshalでdumpできないけど,URI#readするとStringが返ってきてdumpできる.
ruby-1.9.2-p0 > Marshal.dump(open('http://google.com')) TypeError: no marshal_dump is defined for class StringIO ruby-1.9.2-p0 > Marshal.load(Marshal.dump(URI.parse('http://google.com').read)).base_uri => #<URI::HTTP:0x000001011dc390 URL:http://www.google.co.jp/>
POSTもしたいときはWebMockが使えそう.
POST可能なRubyのNet::HTTP偽装テストライブラリWebMock+ - きたももんががきたん。