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')

を挟んだらうまくいった。

More