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のスクリプトを書きました
プログラム初心者な方向けに始めたRailsチュートリアルシリーズです。今回はRubyでスクレイピングをしたいという人向けに『Nokogiri』というライブラリを使ったスクレイピングのチュートリアルを作ってみました! (05-02 08:10) 補足: Windowsではじめての人向けの記事を追加 Nokogiriを使ったRubyスクレイピング [初心者向けチュートリアル] - 酒と涙とRubyとRailsと |
# 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 8859-1(より正式にはISO/IEC 8859-1)はISO/IEC 8859の第一部であり、ラテンアルファベットの文字コード標準である。よりくだけた言い方ではLatin-1と呼ばれる。最初はISOによって開発されたが、後にISOとIECによって合同で保守されている。
ラテン・アルファベットの文字コード標準!もっと早く気づくべきでした。それならば、この文字セットを元にスクレイピングが上手くいかないのも納得です
というわけで、上記のコードのように、文字コードセット(charset)の名称を「CP932」置き換えて無事、UTF-8変換に成功しました
対応は不完全かもしれません
このISO-8859-1という文字セットは、デフォルトの文字コードセットで、rubyでは文字セットが自動取得出来ないときにセットされる模様
そう言う意味では、上記の違ったらCP932に置き換えるのも完全な対策ではないかもしれません
今後、色々なサイトをスクレイピングしてみて、経験値を積んでいきたいと思います
文字コードの変換は過去にも散々なやまされたのですが、なかなかなれません
rubyで、XMLファイルを読み込むために、REXMLを用いて読み込みをするモジュールを作ったのですが、XMLファイルによって以下のようなエラーが出てしまいます。(抜粋)No close tag for /company/shows/show/castLine: 13Position: 970Last 80 unconsumed characters:REXML::ParseExceptionXMLのタグが正当についておらず、エラーになっている様子。ちなみに環境は以下のような感じ。 OS:OSX(Yosemite) Ruby:2.2.4 XMLファイル:ウィンドウズ上のXMLエディタで作成(Windowsのエンコードで保存)最初は、単純に該当の部分のXMLファイルをエ... [ruby]REXMLで、XMLファイルのParse失敗した時の対応方法 - 演劇とかの感想文ブログ |