web-dev-qa-db-ja.com

python3 UnicodeEncodeError: 'charmap'コーデックは位置95-98の文字をエンコードできません:文字は<undefined>にマップされます

1か月前、私はこのGithubに遭遇しました: https://github.com/taraslayshchuk/es2csv

Linuxubuntuに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内では必要ありません。したがって、コードを以下のコードに変更しました。その結果、パッケージはUbuntu16で正しく機能しました。

                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か月後、es2csvパッケージをWindows10オペレーティングシステムで動作させる必要がありました。 Windows 10で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>

誰かがこのエラーメッセージを修正する方法を知っていますか?

2
supernl

これは、Python 3.のopenのデフォルトの動作によるものです。デフォルトでは、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'):
18