LoginSignup
2
0

More than 3 years have passed since last update.

たのしいRuby5版22章で躓いたこと【エンコード関係】

Last updated at Posted at 2019-11-15

Rubyの知識を復習するため、『たのしいRuby第5版』という書籍を読んでいます。
今回は、その22章の「テキスト処理を行う」というところで詰まった箇所とその解決方法を書いていこうと思います。

環境

OS:windows10

詰まったところ

まず、青空文庫から江戸川乱歩『二銭銅貨』をダウンロードします。

nisendouka.rb
#ダウンロードするライブラリ
require "open-uri"

# 青空文庫のURL
url = "https://www.aozora.gr.jp/cards/001779/files/56647_58167.html"
# 書きこむファイル名
filename = "nisendouka.html"

# バイナリモードでファイルを開きます
File.open(filename, "wb") do |f|
    text = open(url).read #ここがよくない
# nisendouka.htmlに書き込む
    f.write text
end

このコードを実行すると、nisendouka.htmlという名前のHTMLファイルが作成され(すでに存在する場合は上書きされます)指定したURLのhtmlファイルが書き込まれます。

問題は次のコード

cut_nisen.rb
htmlfile = "nisendouka.html"
textfile = "nisendouka.txt"

html = File.read(htmlfile, encoding: "UTF-8")

open(textfile, "w:UTF-8") do |f|
    in_header = true
    html.each_line do |line|
        if in_header && /<div class="main_text">/ !~ line
            next
        else
            in_header = false
        end
        break if /<div class="bibliographical_information">/ =~ line
        f.write line
    end
end

処理の内容としては、 <div class="main_text" と <div class="bibliographical_information" で囲まれた部分(本文)を取り出すという処理ですが、これを実行するとエラーが出ました。

# エラー内容
cut_nisen.rb:9:in `=~': invalid byte sequence in UTF-8 (ArgumentError)

初めてみるエラーだったので調べてみました。

エラー原因

調べてみると、どうもUTF-8以外の文字コードで読み込んでいる(?)ことが原因で起こるエラーのようでした。(参考

確かに元の青空文庫の文字コードはSHIFT-JISとなっていたので、それをUTF-8で読み込もうとしたことがよくなかったようです。

そこで青空文庫から読み込む際の文字コードをSHIFT-JIS、HTMLファイルに書き込む際の文字コードをUTF-8と明示することでエラーが解消されました。

nisendouka.rb
# 変更後のコード

#ダウンロードするライブラリ
require "open-uri"

url = "https://www.aozora.gr.jp/cards/001779/files/56647_58167.html"
filename = "nisendouka.html"

File.open(filename, "wb") do |f|
    text = open(url, "r:shift_jis").read #文字コードをshift-jisに指定
    f.write text.encode("utf-8") # 文字コードをutf-8に変更
end

まとめ

スクレイピングなどをするときは文字コードに気を付けることが重要だと思いました。

補足

Stringクラスのencodingメソッドを使うとその文字列の文字コードを確認することができます

sample.rb
str = "こんにちは" 
p str.encoding #=> #<Encoding:UTF-8>

また、Rubyのデフォルトの文字コードはUTF-8ですが、Encoding.default_internalを使うことでencodeメソッドによる文字コードを指定することができます。

手元の環境で実行したのですが、UTF-8のままになってしまいました…。
原因の分かる方、教えていただけると幸いです。

sample2.rb
Encoding.default_internal = "Shift_JIS"
s = "太郎"
puts s.encode

くわしくはこちらのRubyリファレンスをご覧ください。
あとこちらのブログもかなり参考になりそうです(2012年のものなので情報の正確性に注意!)

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0