[ruby]文字コード「iso-8859-1」をUTF8にうまく変換できないときの対応方法

広告

rubyのスクレイピングライブラリのNOKOGIRIを使って、あるページを解析したときに、うまくUTF-8への変換ができずにハマってしまったので、対応法を記録として残しておきます。

目次

結論。iso-8859-1は、日本語の文字コードではありません

よって、日本語への文字コード変換をしようとしても失敗します
rubyでファイルからcharset(文字セット)を自動取得した場合に、Windows文字コード(CP932)のページを誤って「ISO8859−1」と解釈することがあるようです
その為、以下のような一文(6行目)を入れて、読み替えを行いましょう。

    charset=nil
   html=open(url) do |f|
      charset = f.charset
      f.read
   end
   charset="CP932" if charset=="iso-8859-1"
   doc = Nokogiri::HTML.parse(html,nil,charset)

NOKOGIRIでテキストが取得できない

言いたいことは、概ね↑で言い切ったのですが、一応経緯も残しておきます

演劇感想文リンクの更新作業の効率化の為に、スクレイピングに挑戦しようとしています。このサイトの特徴は、他の劇評サイトへのリンクであるため、対象ページのリンク(a href)の一覧をまずは取得しようと考えました

以下のサイトを元にNOKOGIRIのスクリプトを書きました

# encoding:UTF-8
require "open-uri"
require "nokogiri"
class HrefList
  attr_reader :links
  def initialize()
    @links=Array.new()
  end
  def add_links(url)
    charset=nil
    html=open(url) do |f|
      charset = f.charset
      f.read
    end
    doc = Nokogiri::HTML.parse(html,nil,charset)
    lis=doc.css('a')
    lis.each do |li|
      next unless li[:href]
      link = Link.new()
      link.url=li[:href]
      link.text=li.text
      @links << link
    end
  end
end
class Link
  attr_accessor :url , :text
end

クラスHreflistを生成し、add_linkメソッドにスクレイピングしたいURLを渡せば、Linkの配列が取得できるようにしようと考えたクラスです

ところが、UTF-8のページ(演劇感想文リンク)ならば、うまくいくのですが、別のサイトだと何故かまったく日本語が取得できません

サイトをみたところ、UTF-8の文字コードで作成されたページではないようです

しかし、rubyの機能でcharset=f.charsetで自動的に取得されているはず

rubyのencodeの仕様などを見て色々試したのですが、文字化けした文字が表示されるばかり

そもそも、charsetはなんなんだと思いputs文をいれたところ、iso-8859-1という見慣れないキャラクターセットの名称が表示されたのですが、あまり気にせず、encodingなどの仕様を見ながら色々試してました

ネットにもめぼしい情報がなくさんざん悩んだあげく、ISO-8859-1という文字セットを調べました

そもそも日本語の文字セットではない!

ISO/IEC 8859-1 wikipedia

ISO 8859-1(より正式にはISO/IEC 8859-1)はISO/IEC 8859の第一部であり、ラテンアルファベットの文字コード標準である。よりくだけた言い方ではLatin-1と呼ばれる。最初はISOによって開発されたが、後にISOとIECによって合同で保守されている。

ラテン・アルファベットの文字コード標準!もっと早く気づくべきでした。それならば、この文字セットを元にスクレイピングが上手くいかないのも納得です

というわけで、上記のコードのように、文字コードセット(charset)の名称を「CP932」置き換えて無事、UTF-8変換に成功しました

対応は不完全かもしれません

このISO-8859-1という文字セットは、デフォルトの文字コードセットで、rubyでは文字セットが自動取得出来ないときにセットされる模様

そう言う意味では、上記の違ったらCP932に置き換えるのも完全な対策ではないかもしれません

今後、色々なサイトをスクレイピングしてみて、経験値を積んでいきたいと思います

文字コードの変換は過去にも散々なやまされたのですが、なかなかなれません

広告

1 個のコメント

  • コメントを残す

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