はじめに
Rubyのopen-uriライブラリを使ってページのスクレイピングをする際、openメソッドで対象urlを開いてからcharsetメソッドを使ってページの文字コードを取得していましたが、charsetメソッドが具体的にどこから文字コードを参照しているのかがわかっていなかったため、まとめます。
charsetメソッドが参照するリソース
以下公式リファレンスです。
対象となるリソースの文字コードを文字列で返します。Content-Type ヘッダの文字コード情報が使われます。
Rubyリファレンスマニュアル OpenURI::Meta#charset
openメソッドでurlを開いた際の「対象となるリソース」というのは、「ブラウザのデベロッパーツールNetworkパネルで一覧表示されるリソース」を指します。
例としてyahooトップページでデベロッパーツールを開いて確認してみます。
https://www.yahoo.co.jp/
Networkタブで「www.yahoo.co.jp」のリソースを選択し、「Headers」タブで表示した画像です。
「Response Headers」の「content-type」項目に「charset=UTF-8」と記述されています。
charsetメソッドはこの「charset=UTF-8」を参照して文字コードを取得しているということです。
実際にcharsetメソッドを使ってyahooの文字コードを取得してみます。
require 'open-uri'
url = 'https://www.yahoo.co.jp/'
charset = nil
html = open(url) do |f|
charset = f.charset
f.read
end
p charset
$ ruby sample1.rb
"utf-8"
charsetメソッドでいつも文字コードを取得できるとは限らない
上の例で見たように、charsetメソッドが参照するのはリソースの「content-type」項目です。
つまりリソースの「content-type」項目に「charset」が書かれていないと参照できません。
例えば、zozotownトップページには「content-type」項目に「charset」が記述されていません。
https://zozo.jp/
「content-type」項目に「charset」の記述が見当たりません。
zozotownトップページを指定して文字コードを取得してみます。
require 'open-uri'
url = 'https://zozo.jp/'
charset = nil
html = open(url) do |f|
charset = f.charset
f.read
end
p charset
$ ruby sample2.rb
nil
結果のように、「content-type」に記述がないと、charsetメソッドで取得した結果はnilとなります。
では実際zozotownはどの文字コードで書かれているのでしょうか。
ページで「ctrl + u」を押してページのソースを表示すると、
zozotownのページは「Shift_JIS」で書かれていました。
このようにページによってcharsetメソッドが文字コードを取得できない場合があるので注意が必要です。