web-dev-qa-db-ja.com

Python文字列のu '\ ufeff'

次のパターンでエラーが発生します。

UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)

u'\ufeff'が何であるかはわかりませんが、Webスクレイピング中に表示されます。どうすれば状況を改善できますか? .replace()文字列メソッドは機能しません。

95
James Hallen

Unicode文字U+FEFFはバイトオーダーマーク(BOM)であり、ビッグエンディアンとリトルエンディアンUTF-16エンコーディングの違いを示すために使用されます。適切なコーデックを使用してWebページをデコードすると、Pythonがそれを削除します。例:

#!python2
#coding: utf8
u = u'ABC'
e8 = u.encode('utf-8')        # encode without BOM
e8s = u.encode('utf-8-sig')   # encode with BOM
e16 = u.encode('utf-16')      # encode with BOM
e16le = u.encode('utf-16le')  # encode without BOM
e16be = u.encode('utf-16be')  # encode without BOM
print 'utf-8     %r' % e8
print 'utf-8-sig %r' % e8s
print 'utf-16    %r' % e16
print 'utf-16le  %r' % e16le
print 'utf-16be  %r' % e16be
print
print 'utf-8  w/ BOM decoded with utf-8     %r' % e8s.decode('utf-8')
print 'utf-8  w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig')
print 'utf-16 w/ BOM decoded with utf-16    %r' % e16.decode('utf-16')
print 'utf-16 w/ BOM decoded with utf-16le  %r' % e16.decode('utf-16le')

EF BB BFはUTF-8でエンコードされたBOMであることに注意してください。 UTF-8には必要ありませんが、署名としてのみ機能します(通常はWindowsで)。

出力:

utf-8     'ABC'
utf-8-sig '\xef\xbb\xbfABC'
utf-16    '\xff\xfeA\x00B\x00C\x00'    # Adds BOM and encodes using native processor endian-ness.
utf-16le  'A\x00B\x00C\x00'
utf-16be  '\x00A\x00B\x00C'

utf-8  w/ BOM decoded with utf-8     u'\ufeffABC'    # doesn't remove BOM if present.
utf-8  w/ BOM decoded with utf-8-sig u'ABC'          # removes BOM if present.
utf-16 w/ BOM decoded with utf-16    u'ABC'          # *requires* BOM to be present.
utf-16 w/ BOM decoded with utf-16le  u'\ufeffABC'    # doesn't remove BOM if present.

utf-16 codec requires BOMが存在するか、Pythonはデータがビッグエンディアンかリトルエンディアンかを判断できないことに注意してください。

136
Mark Tolonen

Python 3でこれに遭遇し、この質問を見つけました(そして solution )。ファイルを開くとき、Python 3はencodingキーワードをサポートし、エンコードを自動的に処理します。

これがない場合、BOMは読み取り結果に含まれます。

>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'

正しいエンコーディングを与えると、BOMは結果で省略されます:

>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'

ちょうど2セントです。

74
siebz0r

その文字は BOM または "Byte Order Mark"です。通常、ファイルの最初の数バイトとして受信され、残りのデータのエンコードを解釈する方法を示します。キャラクターを削除するだけで続行できます。ただし、「ascii」に変換しようとしていることがエラーに示されているため、おそらく何をしようとしても別のエンコーディングを選択する必要があります。

4
swstephe

スクレイピングしているコンテンツは、ASCIIテキストではなくUnicodeでエンコードされており、ASCIIに変換されない文字を取得しています。正しい「翻訳」は、元のWebページが何であるかによって異なります。 PythonのUnicodeページ は、動作の背景を示します。

結果を印刷しようとしていますか、それともファイルに貼り付けようとしていますか?このエラーは、問題を引き起こしているデータをwriteであり、それを読み取っていないことを示唆しています。 この質問 は修正を探すのに適した場所です。

4
theodox

この問題は、基本的にpythonコードをTF-8またはUTF-16エンコーディングで保存するときに発生します。これは、pythonの先頭に特殊文字を追加するためですエンコード形式を識別するためのコード(テキストエディターでは表示されません)。ただし、コードを実行しようとすると、1行目で構文エラーが発生します。つまり、PythonコンパイラーはASCII encodingであるため、コードの開始です。 read()関数を使用してファイルのコードを表示すると、返されたコードの先頭に'\ ufeff'が表示されます。この問題の最も簡単な解決策は、単にエンコーディングをASCII encodingに戻す(このために、コードをメモ帳にコピーして保存することができます覚えておいてください!ASCII encoding ...これが役立つことを願っています。

0
Jagdish Chauhan