2017-04-08 6 views
0

私はProject Gutenbergからダウンロードした大きな文字列を持っています。私はそれを私のコンピュータに保存しようとしていますが、UnicodeEncodeErrorを取得しています。それを修正する方法や無視する方法がわかりません。私は、ファイルの先頭にBOMを削除しようとした、utf8ファイルを保存するときにUnicodeEncodeErrorを無視する

UnicodeEncodeError: 'charmap' codec can't encode character '\ufeff' in position 0: character maps to <undefined> 

まず:

from urllib import request 

# Get the text 
response = request.urlopen('http://www.gutenberg.org/files/2701/2701-0.txt') 
# Decode it using utf8 
raw = response.read().decode('utf8') 
# Save the file 
file = open('corpora/canon_texts/' + 'test', 'w') 
file.write(raw) 
file.close() 

これは私に次のエラーを与える

# We have to get rid of the pesky Byte Order Mark before we save it 
raw = raw.replace(u'\ufeff', '') 

が、私は同じエラーを取得し、別のポジション番号でちょうど:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 7863-7864: character maps to <undefined> 

私はその地域で見れば、私は問題の文字を見つけることができないので、私は削除するかわからない:

raw[7850:7900] 

だけ出力します:

ようには見えません
' BALLENA,    Spanish.\r\n  PEKEE-NUEE-' 

をそれは問題になるでしょう。

file = open('corpora/canon_texts/' + 'test', 'w') 
try: 
    file.write(raw) 
except UnicodeEncodeError: 
    pass 
file.close() 

をしかし、これは私に0サイズのファイルを与え、テキスト全体をスキップ:

だから、私はtry文で悪い行をスキップしようとしました。

どうすればこの問題を解決できますか?

EDIT:

カップルの人は、 '\のufeffは' UTF-16であることを指摘しています。

# Get the text 
response = request.urlopen('http://www.gutenberg.org/files/2701/2701-0.txt') 
# Decode it using utf16 
raw = response.read().decode('utf-16') 

しかし、私はこのエラーを取得する前に、私もデータをダウンロードすることはできません:私は、UTF-16への切り替えを試みた

UnicodeDecodeError: 'utf-16-le' codec can't decode byte 0x0a in position 1276798: truncated data 

SECOND EDITを:

私もUTF-8でデコードしてみましたそれはBOMが含まれているためu'\ufeff' in Python stringで提案されているように-sigが、私はそれを保存しようとすると、私は戻って、このエラーによ:

UnicodeEncodeError: 'charmap' codec can't encode characters in position 7863-7864: character maps to <undefined> 
+0

「\ ufeff」はutf-16のBOMであり、あなたはutf-8としてデコードしようとしています。 – TemporalWolf

+0

可能性のある[u '\ ufeff' in Python string](http://stackoverflow.com/questions/17912307/u-ufeff-in-python-string) – TemporalWolf

+0

例外の原因となっている文字を確認するには、 'ascii(raw [7850:7900])'を試してください。標準の 'repr()'形式では見えない、珍しい空白文字やソフトハイフンなどがあるかもしれません。 – lenz

答えて

1

デコードや再エンコードするファイルをドロップすることができます(終了UTF-8ラインである)非常に最後の文字0x0a、とのトラブルを抱えてのように見えますそれをディスクに保存するのは無意味です。ちょうどあなたがダウンロードしたバイトを書き出し、そしてあなたは、ディスク上のファイルを持っています:

raw = response.read() 
with open('corpora/canon_texts/' + 'test', 'wb') as outfile: 
    outfile.write(raw) 

これは、ディスクあなたがダウンロードしたかを正確にに書き込むための唯一の信頼できる方法です。

遅かれ早かれファイルを読み込んで作業したいので、エラーを考えてみましょう。あなたは完全なスタックトレースを提供していませんでしたが(常に悪い考え方です)、エラーはの間にはデコードされません。デコードのステップは成功しました。このエラーは、file.write(raw)行に発生している必要があります。これはテキストが保存用にエンコードされています。しかし、それはどのようなエンコーディングに変換されていますか?エンコードを指定せずにfileを開いたので、誰も知らない!取得しているエンコーディングは、お住まいの地域、OS、おそらく干潮や天気予報によって異なります。要約すると、エンコーディングを指定します。

+0

ええ、そうです:OPの環境での出力エンコーディングのデフォルトは、明らかにいくつかの8ビットエンコーディングです。エラーメッセージ( 'charmap'コーデック)が示唆するように、いくつかの文字を扱うことはできません。 BOMはデコードされた文字列に含めるものではないので、入力エンコーディングは 'utf-8-sig'でなければなりません。 – lenz

+0

あなたのアプローチを使ってディスクに保存しますが、あなたのコードで読み込もうとするとファイルが消去され、変数の文字列は空の文字列になります – jss367

+0

ファイルを読み書きするプロセスが混乱していると思います。 "w"または "wb"モードでファイルを開くと、実際にすぐ前の内容が消去されます。ファイルを読み込むには、 "r"モードで(またはモードがない場合は、デフォルトで "r"に)ファイルを開きます。 [入力と出力](https://docs.python.org/3/tutorial/inputoutput.html)のPythonチュートリアルを読んでください。とにかく_this_質問は、ファイルをダウンロードしてディスクに保存する方法に関するものでした。メモ帳(または別のエディタ)を使用して上記のコードが動作し、ファイルがダウンロードされたことを確認します。ファイルの読み込みに問題がある場合は、新しい質問をしてください。 – alexis

-1

U + feffはUTF-16です。代わりにそれを試してください。

+0

これは私に新しいエラーをもたらします。私は質問を編集しました。 – jss367

-1

.decode(encoding="utf-8", errors="strict")は、内蔵機能としてエラー処理を提供しています:

The default for errors is 'strict' , meaning that encoding errors raise a UnicodeError . Other possible values are 'ignore' , 'replace' and any other name registered via codecs.register_error() , see section Error Handlers .

おそらく最も安全なオプションでは、何の記録を持っているので、バックスラッシュでエンコーディングエラーをエスケープします

decode("utf8", errors='backslashreplace') 

ですデコードに失敗しました。

便利なことに、Moby Dickのテキストには円記号が含まれていないため、デコードに失敗した文字を確認するのは簡単です。

このテキストの奇妙な点は、utf-8のWebサイトでは\efeffutf-16のBOMです。 utf-16でデコード、それはあなただけで、おそらく安全にちょうど

decode("utf-16", errors='ignore') 
+0

キャラクタ「\ ufeff」はBOMですが、これはデコードされた文字列なので、UTF-16のBOMであるとは言えません。しかし、BOMはデコードされた文字列には存在してはいけません。そのため、正しい入力エンコーディングが得られるようにする必要があります(BTEは、必要に応じて、 'b' \ xfe \ xff 'おそらく 'utf-8-sig'でしょう。入力がUTF-16であると思われる場合、 'b '\ xfe \ xff'は有効なUTF-8バイトシーケンスではないので、UTF-8によるデコードは直ちに失敗します。 – lenz

関連する問題