1. ホーム
  2. python-3.x

[解決済み] python3 UnicodeEncodeError: 'charmap' コーデックは位置 95-98 の文字をエンコードできない: 文字は <undefined> にマップされる。

2022-02-18 02:57:10

質問

1ヶ月前、このGithubに出会いました。 https://github.com/taraslayshchuk/es2csv

Linuxのubuntuにpip3経由でこのパッケージをインストールしました。このパッケージを使おうとしたとき、このパッケージはpython2用であるという問題に遭遇しました。 コードに潜り込み、すぐに問題を発見しました。

                for line in open(self.tmp_file, 'r'):
                timer += 1
                bar.update(timer)
                line_as_dict = json.loads(line)
                line_dict_utf8 = {k: v.encode('utf8') if isinstance(v, unicode) else v for k, v in line_as_dict.items()}
                csv_writer.writerow(line_dict_utf8)
            output_file.close()
            bar.finish()
        else:
            print('There is no docs with selected field(s): %s.' % ','.join(self.opts.fields))

このコードではユニコードのチェックを行っていましたが、python3では不要なため、以下のコードに変更しました。その結果、Ubuntu 16で正常に動作するようになりました。

                for line in open(self.tmp_file, 'r'):
                timer += 1
                bar.update(timer)
                line_as_dict = json.loads(line)
                # line_dict_utf8 = {k: v.encode('utf8') if isinstance(v, unicode) else v for k, v in line_as_dict.items()}
                csv_writer.writerow(line_as_dict)
            output_file.close()
            bar.finish()
        else:
            print('There is no docs with selected field(s): %s.' % ','.join(self.opts.fields))

しかし、その1カ月後、Windows 10のOSでes2csvパッケージを動作させる必要が出てきたのです。Windows10でes2csvと全く同じ調整をした後、es2csvを実行しようとすると、次のようなエラーメッセージが表示されました。

    PS C:\> es2csv -u 192.168.230.151:9200 -i scrapy -o database.csv -q '*'
Found 218 results
Run query [#######################################################################################################################] [218/218] [100%] [0:00:00] [Time: 0:00:00] [  2.3 Kidocs/s]
Write to csv [#                                                                                                                     ] [2/218] [  0%] [0:00:00] [ETA: 0:00:00] [  3.9 Kilines/s]T
raceback (most recent call last):
  File "C:\Users\admin\AppData\Local\Programs\Python\Python36\Scripts\es2csv-script.py", line 11, in <module>
    load_entry_point('es2csv==5.2.1', 'console_scripts', 'es2csv')()
  File "c:\users\admin\appdata\local\programs\python\python36\lib\site-packages\es2csv.py", line 284, in main
    es.write_to_csv()
  File "c:\users\admin\appdata\local\programs\python\python36\lib\site-packages\es2csv.py", line 238, in write_to_csv
    csv_writer.writerow(line_as_dict)
  File "c:\users\admin\appdata\local\programs\python\python36\lib\csv.py", line 155, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "c:\users\admin\appdata\local\programs\python\python36\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode characters in position 95-98: character maps to <undefined>

このエラーメッセージを修正する方法をご存知の方はいらっしゃいますか?

解決方法は?

のデフォルトの動作が原因です。 open をPython 3で使用することができます。デフォルトでは、Python 3 はファイルをテキストモードで開きます。これは、読み込むすべての文字に対して utf-8 や ASCII のようなテキストデコードを適用する必要があることを意味します。

Pythonはあなたのロケールを使って最も適したエンコーディングを決定します。OS XとLinuxでは、これは通常UTF-8です。Windowsでは、メモ帳の動作に合うようにwindows-1252のような8ビット文字セットを使用します。

8ビットの文字セットは文字数が限られているため、文字セットでサポートされていない文字を書こうとすると、非常に簡単に終わってしまいます。例えば、西ヨーロッパの文字セットであるWindows-1252でヘブライ語の文字を書こうとした場合。

この問題を解決するためには、以下の方法でエンコーディングの自動選択を無効にする必要があります。 open で、UTF-8を使用するようにハードコードしてください。

for line in open(self.tmp_file, 'r', encoding='utf-8'):