capybara-mechanizeでSJISのページを扱う
[20130729 追記]
Ruby 1.8 前提の書き方になっていたのと、Ruby 1.9 以降を使っている場合に Capybara-mechanize 1.0 前後で挙動が変わる記述を追加。
scrapeはmechanizeらしくUTF-8のままでok
click_on( '次へ>>' )
みたいな記述は UTF-8 で書いたものがそのまま動く。
テスト時はUTF-8への変換が必要
Ruby 1.8 では
body.toutf8
でよかった。
it {
body.toutf8.should include('ほげげげ')
}
みたいな感じ。
kconv を require した覚えがないのに kconv が動いてるのはなんでだろう。
まーいっか。
もし&#xxx;形式になってたら
(Ruby 1.8で動かしている場合は $KCODE = 'u' したうえで)
CGI.unescapeHTML(body)
でいいみたい。
ちなみにSelenium WebDriverの場合
全部 UTF-8 で扱える。Selenium で書いていって Mechanize で CI に乗せる、といった運用を考えている場合はここが食い違うので注意が必要。
Ruby 1.9+ の場合
いずれも Mechanize 2.7.1 で試した。
HTTP Response Header に charset がない場合の挙動が Capybara 1 と 2 の間、あるいは Capybara-mechanize 0.x と 1.x の間で異なっているので注意が必要。
たぶんイマドキは charset UTF-8 に統一してあれば response header に入ってそうな気はするけど、古い日本のサイトだとダメな気がする。
'capybara-mechanize', '< 1.0'
自動で正しく encoding を判別できていたので
.encode('UTF-8')
で OK
'capybara-mechanize', '> 1.0'
HTML の中に charset 指定があってもダメで HTTP Response の charset だけをアテにして encoding の判別に失敗するようになってしまい Encoding::UndefinedConversionError: … from ASCII-8BIT to UTF-8 エラーが出る。
仕方ないので
.toutf8.force_encoding('UTF-8')
を挟んだらうまくいった。