LoginSignup
5
3

WindowsでUnicodeDecodeError: 'cp932' codec can't decode byte... が出たときの対処方法

Posted at

Case1. 自分で作ったところで発生した場合

  1. 自分でopen関数などを書いた場合は対象のファイルがShift_JISであるかどうか確認します。
    chardetで確認することができます
import chardet
with open(file, "rb") as f:
  result = chardet.detect(f.read())

1-1. ファイルがShift_JISでないならShift_JISに変換します。

with codecs.open(file, "r", "utf-8") as file:
    row_data = []
    for row in file:
       row_data.append(row)

with codecs.open(file, "w", "shift_jis") as file:
    for row in row_data:
        file.write(row)

1-2. ファイルをUTF-8で開きたい場合はencodingを付け足します。

f = open(file, encoding="utf-8")

そのうえでライブラリがopen関数などを読んでいる場合はシステムがどのエンコードを使っているかを確認します。

Case2. 依存しているライブラリから発生している場合

pythonで使っているデフォルトのエンコーディングがShift_JIS(CP932)になっており、基本のエンコーディングのUTF-8を読み込めなくなっている可能性があり増す。

以下のスクリプトを実行してみてください。

import os
import sys
import locale
print(os.environ.get("PYTHONIOENCODING"))
print(sys.getdefaultencoding())
print(sys.getfilesystemencoding())
print(sys.stdout.encoding)
print(locale.getpreferredencoding())

一つでも cp932 があるとそれが原因でファイルを読み込めない場合があります。

それぞれのケースで対処方法を見ていきます。

os.environ.get("PYTHONIOENCODING")でcp932が出た場合

sys.getdefaultencoding()でcp932が出た場合

以下で修正できます。

os.environ["PYTHONIOENCODING"] = "utf-8"

sys.getfilesystemencoding()でcp932が出た場合

あまりないと思いますが以下で直せます。

import sys
sys.getfilesystemencoding = lambda: 'UTF-8'

sys.stdout.encodingでcp932が出た場合

以下で修正できます。

sys.stdout.reconfigure(encoding='utf-8')

locale.getpreferredencoding()でcp932が出た場合

おそらく最もありえると思われるパターンです。
Windowsでのロケールを変更します。
以下が参考になります。

コントロールパネルより「地域」→「管理」から

img1

「システムロケールの変更」を選んでください。

img2

「ベータ:ワールドワイド言語サポートでUnicode UTF-8を使用」にチェックを入れます。

img3

これで使われるロケールのエンコーディングがUTF-8になります。

別の対処法

Powershellで設定もできます。

New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'ACP' -Value '65001' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'OEMCP' -Value '65001' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'MACCP' -Value '65001' -PropertyType String -Force;

戻すときは以下です。

New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'ACP' -Value '932' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'OEMCP' -Value '932' -PropertyType String -Force;
New-ItemProperty -LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Nls\CodePage' -Name 'MACCP' -Value '932' -PropertyType String -Force;

注釈:cp65001とは?

UTF-8の別名みたいです。

pythonでは以下のように出力されます。

import codecs
codecs.lookup('cp65001')
<codecs.CodecInfo object for encoding utf-8 at 0x1a62631cbe0>
5
3
1

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