UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 100-101: illegal cp932 surrogate
とエラーが出ました。
with io.open('data/xxx2.csv', 'w', encoding='cp932') as fout: with io.open('data/xxx.csv', encoding='utf-8') as fin: fout.write(fin.read())
とコードを書きました。
csvファイルの中身がutf_8で記述されているのですが、それをshift-jisへ変換したいです。
どう直せばいいのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
文字コードの変換を行う際には一回Unicodeを経由する必要があります。
utf-8を一度デコードしてからshift-jisにエンコードしましょう
python
1with io.open('data/xxx2.csv', 'w') as fout: 2 with io.open('data/xxx.csv', encoding='utf-8') as fin: 3 fout.write(fin.read().decode('utf-8').encode("shift-jis"))
投稿2017/03/20 10:26
総合スコア72
0
エラーメッセージからすると、元のファイルの 520byte 目からの2バイトが、Shift-JIS(CP932) の範囲を逸脱しているため、UTF-8 から変換できない、のです。
エラーを引き起こしているところに何が書かれているかによりますが、CP932 ではなく、shift_jisx0213 に変換すると、あるいは変換できるかもしれません。
参考:Python マニュアル
投稿2017/03/15 08:25
編集2017/03/15 08:34総合スコア13703
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/03/15 09:03
2017/03/15 09:19
2017/03/15 09:25
2017/03/15 09:33
2017/03/15 09:37
2017/03/15 09:37
2017/03/15 09:48
0
Python2 をお使いのようなので、fin.read() の結果は、str(Unicodeではない)となっています。
str → unicode に utf-8で変換(decode)したあとに、
unicode → str に shift_jis or cp932 で変換(encode)して、書き込む必要があります。
このどちらかの変換がうまくいかない場合もあります。
その際には、変換時に 'replace' や 'ignore' などを引数で指定してごまかす必要が出てくるかもしれません。
(変換失敗が問題になるのであれば、問題になる文字列を見つけて、一つ一つ丁寧に置き換えをする必要があります)
なお、python3 では、別の処理になります。
投稿2017/03/21 07:05
総合スコア313
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
0
エラーメッセージから、fin.read()時、すなわち元ファイルの(UTF-8エンコードされているとみなした)バイト列からpythonのunicode型として読込時に発生したエラーだと考えらえれます。
まずはfout.write(fin.read())
の部分を
Python
1temp = fin.read() 2fout.write(temp)
のように書き換えて、read,writeどちらでエラーが発生しているかを確認(特定)してください。
もしread時に発生しているのであれば、元ファイルが本当にutf-8
エンコードされているか確認してください。
たとえば以下のようなコードで実際のバイト列を確認することができます。
Python
1import io 2with io.open( "data/xxx.csv", "rb") as fin: 3 data = fin.read() 4 for i in range(len(data)): 5 print("[%d][%02X]" % (i,ord(data[i])))
ちなみに「㎥」などcp932
で表現できない文字を含むunicode
文字列をcp932
でファイル出力しようとすると
UnicodeEncodeError: 'cp932' codec can't encode character u'\u33a5' in position 18: illegal multibyte sequence
というエラーが発生します。
2017/03/21追記:io.read()
が返す文字列の型について
テキストモード (デフォルトか mode 引数に 't' が含まれている場合) では、ファイルの内容は unicode 文字列として返され、バイト列はプラットフォーム依存のエンコーディングか、 encoding が指定された場合は指定されたエンコーディングを使ってデコードされます。
と記載されているとおり、質問文のコードではio.open
時にエンコーディングを指定しているので、fin.read()で返される文字列は、内部でutf-8
でデコードされたunicode
型となります。
すなわちfin.read().decode('utf-8')する必要はありません。
確認コード
>python Python 2.7.12 |Anaconda custom (64-bit)| (default, Jun 29 2016, 11:07:13) [MSC v .1500 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. Anaconda is brought to you by Continuum Analytics. Please check out: http://continuum.io/thanks and https://anaconda.org >>> import io >>> with io.open('data.csv',encoding='utf-8') as fin: ... tmp = fin.read() ... >>> type(tmp) <type 'unicode'> >>> repr(tmp) "u'a'"
投稿2017/03/15 09:09
編集2017/03/21 07:57総合スコア38262
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
関連した質問
UnicodeDecodeError: 'utf-8' codec can't decode bytes in position 520-521: illegal cp932 surrogate
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。