Rubyの知識を復習するため、『たのしいRuby第5版』という書籍を読んでいます。
今回は、その22章の「テキスト処理を行う」というところで詰まった箇所とその解決方法を書いていこうと思います。
環境
OS:windows10
詰まったところ
まず、青空文庫から江戸川乱歩『二銭銅貨』をダウンロードします。
#ダウンロードするライブラリ
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ファイルが書き込まれます。
問題は次のコード
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と明示することでエラーが解消されました。
# 変更後のコード
#ダウンロードするライブラリ
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メソッドを使うとその文字列の文字コードを確認することができます
str = "こんにちは"
p str.encoding #=> #<Encoding:UTF-8>
また、Rubyのデフォルトの文字コードはUTF-8ですが、Encoding.default_internalを使うことでencodeメソッドによる文字コードを指定することができます。
手元の環境で実行したのですが、UTF-8のままになってしまいました…。
原因の分かる方、教えていただけると幸いです。
Encoding.default_internal = "Shift_JIS"
s = "太郎"
puts s.encode
くわしくはこちらのRubyリファレンスをご覧ください。
あとこちらのブログもかなり参考になりそうです(2012年のものなので情報の正確性に注意!)