簡単なスクレイピングで取得したデータをカンマ区切りのCSV形式で出力が出来たので、続けてCSVファイルを読み込んでみたところ少しハマったのでメモ。(昨日の記事の続き)
CSVファイルの読み込み
CSVファイルの読み込みには、そのものズバリ「csv」というライブラリがあるようなので、これを使ってみる。
require 'csv' CSV.foreach("name_list.csv") do | row | name_list.push(row[1]) # 名前, フリガナ end
読み込みエラー
すると、「CSVファイルの8911行目に変なデータがあるぞ」みたいなエラーが出て止まる。
Traceback (most recent call last): 9: from csv_read_test.rb:9:in `<main>’ 8: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1141:in `foreach’ 7: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1289:in `open’ 6: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1142:in `block in foreach’ 5: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1763:in `each’ 4: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1821:in `shift’ 3: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1821:in `loop’ 2: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1867:in `block in shift’ 1: from /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1867:in `each’ /Users/xxx/.rbenv/versions/2.5.1/lib/ruby/2.5.0/csv.rb:1911:in `block (2 levels) in shift’: Illegal quoting in line 8911. (CSV::MalformedCSVError) |
どうもダメなデータはコレみたい。
データにダブルクォート(”)を含むとダメ、というよりエスケープが必要になるのでCSV形式でファイルを書き出す際、次のようにエスケープするように変更。
name.gsub!(/\”/, ‘””‘) |
これで
「”サイトウ””JxJx””ジュン”,”サイトウ ジェイジェイ ジュン”」
とダブルクォートがエスケープできたので、データを読み込み可能に。
補足1:CSVについて
CSV(comma-separated values)はカンマ区切りでデータを記述したテキストデータ。
歴史や背景なんかの詳細はWikipediaに。
また、昔から使われているデータ形式だけど、2005年に一応?仕様化(RFC4180)されている模様。
補足2:読み込み時にオプション指定すればオッケーかも
liberal_parsing のオプションを利用すると、ダブルクォートで囲ってないデータであること前提だけど、データ中に出てくるダブルクォートは救済してもらえる模様。(とはいえ、データはRFC4180に準拠した方が良いと思うけど)
CSV.foreach(“name_list.csv”, liberal_parsing: true) do | row | name_list.push(row[1]) # 名前, フリガナ end |
まとめ
CSVデータは手軽に作成できる一方、「とりあえずカンマ区切りにしとけば良いんでしょ」とか考えているとデータ内容次第で読み込み時にハマる可能性あり。(使用するライブラリによっても対応はまちまちっぽいので気をつけたい)
CSVを使う際には「データ自体にカンマ、ダブルクォート、改行あたりを含むかどうか」は最低限でも考慮が必要ですよ、と。
コメント