Nokogiriを弄ぶ

ちょっくら趣味でWebスクレイピングしてみる。

普段ほとんど使わないRubyで、Nokogiriというライブラリを使ってみたところ、サイトによってうまくパースできないことがあった。

うーん、おかしい…とパケットキャプチャ結果をしばし眺める。すると、content-encodingに’gzip’がある場合にうまくいっていない。gzipされたHTTPレスポンスをそのままNokogiriでパースしては駄目なようだ。

てっきりnet/httpかnokogiriが、gzipレスポンスを展開して、自動的に処理してくれるものと思いこんでいました(それとも、何かうまいやり方があるのかな?)。下のようなコードを書くことで、gzipにも対応できましたとさ。

require "nokogiri"
require "net/http"
require 'zlib'
require 'pp'
class DocUtil
def self.getDoc(url)
content = self.getContent(url)
doc = Nokogiri::HTML.parse(content)
return doc
end
def self.getContent(url)
uri =URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
response = http.get(uri.request_uri)
#encodingを確認する
encoding=response['content-encoding']
content=nil
if encoding then
#圧縮あり
case encoding
when 'gzip' #gzip
i=Zlib::GzipReader.new(StringIO.new(response.body))
content=i.read
when 'deflate' #deflate
i=Zlib::Inflate.new
content=i.inflate(response.body)
else
raise "Unknown: " + encoding
end
else
content=response.body  #圧縮無しの場合
end
return content
end
end
doc = DocUtil.getDoc("http://twitter.com")
pp doc  #パース結果を表示

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です