LoginSignup
3
2

More than 3 years have passed since last update.

備忘録(CSVファイル読み込み時のUnicodeDecodeError対策)

Last updated at Posted at 2020-09-16

pythonで自動化とかできるんでしょ~?よろしく~、って言われたので頑張る記録 その1

~~結論だけ先に書いておく~~
open(CSVファイル,encoding =文字コード)で指定する時、
 文字コードには「CSVファイルに使われている文字コード」を使えば大丈夫。
 今回は日本語を含むファイルだったのでShift-jisで指定が必要だった。

~~どうでもいい日記~~ 社内のソフトでデータをCSVに出力する
→担当者がいい感じにエクセルファイル上で成形する
→エクセルファイルをメールで先方に送る
pythonを使って上記作業をうまいこと自動化するように言われたのでゼロスタートで頑張ることになった。
pythonについては完全に素人だが、VBAの知識が多少あるなら何とかなるらしい。本当かよ。
~~ここまで日記~~

~~主題~~
・CSVファイルを読み込んだらUnicodeDecodeErrorが出たので直したい

~~ここから状況説明~~
Google Colaboratoryを使ってpythonの基本機能を確認から開始した。
適当なCSVファイルをグーグルドライブ直下に置く。
google Colaboratoryから新しいNotebookを作成する。
csvを読み込んで出力するサンプルプログラムを試す。
Ref:https://note.com/092i034i/n/n76f2c2de197

test
import csv #これを書いておくとCSVファイルが扱えるっぽい

csvfile = open('/content/drive/My Drive/test.csv') #csvファイルをpythonの変数csvfileに取り込んだ
reader = csv.DictReader(csvfile) #csvfileの情報を何らかの形でreaderという変数に放り込んだ

for row in reader: #まだ良く分かってない。繰り返し処理っぽいけど・・・。

 print(row) #変数rowの中身を出力するやつ

しかし、コンパイルが通らない。エラーが出る。

error-message
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-30-e6400dcd8fdb> in <module>()
      4 reader = csv.DictReader(csvfile)
      5 
----> 6 for row in reader:
      7  print(row)

英語の成績が致命を通り越して落命レベルであり、スマブラの「Break the target!」のアナウンスさえ異界の言語と思っていた身としては、この時点で既に気分がどんよりしてきているが、まあ一個ずつ取り組むしか無い。

見たところ、変数readerの中身をrowに代入するときのデコード(復号化)に失敗しているのだが、
csvfile=open(test.csv)の処理では何もエラーが出ていない。

この結果から考えたプログラム処理の流れ
1.ドライブ上のCSVファイルをエンコード(暗号化)してpythonの変数csvfileに取り込む
2.変数csvfileの中身を、エンコードされたままcsv.dictreaderという法則で変数Readerに代入
3.変数readerの中身を復号化して変数row に移し替える(ここで復号に失敗してエラーが出た)
4.変数Rowの中身を1行目から最後まで出力する

よってreaderの中身をrowに移すときの復号方式に何か問題がある・・・と、思っていたのだが、
エラーメッセージをネットで調べるとどうも違うらしい。

正しい処理の流れっぽいもの
1.ドライブ上のCSVファイルは日本語を含むのでShift-jisでエンコードされていた
2.しかし、特に何も指定がないと、pythonはCSVファイルの中身をUTF-8でエンコードして変数csvfileに取り込む
3.この時、変数csvfileの中身は「Shift-jisのファイルをUTF-8で無理矢理エンコードした文字化け状態」になっている
4.しかし、なぜかこの状態でもcsv.dictreaderという法則で変数csvfileから変数Readerに代入することはできる
5.変数readerの中身を復号化して変数row に移し替える(ここでデコードできないことで初めて文字化けが分かるらしい)
6.変数Rowの中身を1行目から最後まで出力する

何故csv.dictreaderではOKなのか分からないが、
直したらコンパイルが通ってしまったのでひとまずはそういうものだと割り切ることにする。

エンコードの時点で問題が発生していても、pythonの処理でそれが発覚するのはデコード時らしい。
これは多分、俺のエンコード・デコードに関する知識が不十分なせいで意味が分からない点なんだけど・・・メインの自動化の話からは逸れるので今回は追うのを諦める。

しかし、初日が終わってまだCSVファイルの読み取りしか出来ていないが本当に大丈夫か。
俺がオリマーならホコタテ星から出られず土に還るペースだぞ。
VBAの知識あれば大丈夫って本当に本当か。不安。

補足:直したらコンパイルが通ったときのコード
import csv

csvfile = open('/content/drive/My Drive/test.csv',encoding="shift-jis")  #日本語csvファイルをshift-jisで取り込み
reader = csv.DictReader(csvfile)

for row in reader:
 print(row) 
3
2
0

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
3
2