次のパターンでエラーが発生します。
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)
何なのかわからないu'\ufeff'
、私がWebをこするときに表示されます。どうすれば状況を改善できますか?.replace()
文字列のメソッドは機能しません。
次のパターンでエラーが発生します。
UnicodeEncodeError: 'ascii' codec can't encode character u'\ufeff' in position 155: ordinal not in range(128)
何なのかわからないu'\ufeff'
、私がWebをこするときに表示されます。どうすれば状況を改善できますか?.replace()
文字列のメソッドは機能しません。
回答:
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
コーデックでは BOMが存在する必要があることに注意してください。そうしないと、Pythonはデータがビッグエンディアンかリトルエンディアンかを認識しません。
私はPython 3でこれに遭遇し、この質問を見つけました(そして解決策))。ファイルを開くとき、Python 3はエンコーディングキーワードをサポートし、エンコーディングを自動的に処理します。
これがない場合、BOMは読み取り結果に含まれます。
>>> f = open('file', mode='r')
>>> f.read()
'\ufefftest'
正しいエンコーディングを指定すると、BOMは結果で省略されます。
>>> f = open('file', mode='r', encoding='utf-8-sig')
>>> f.read()
'test'
ちょうど私の2セント。
スクレイピングするコンテンツは、ASCIIテキストではなくUnicodeでエンコードされており、ASCIIに変換されない文字を取得しています。正しい「翻訳」は、元のWebページがそれをどう思ったかによって異なります。 Pythonのユニコードページは、それがどのように機能するかの背景を提供します。
結果を印刷したり、ファイルに貼り付けたりしようとしていますか?エラーは、問題を引き起こしているデータを読み取っているのではなく、書き込んでいることを示しています。この質問は、修正を探すのに適した場所です。
これは、Mark Tolonenからの回答に基づいています。文字列には、「|」で区切られた「test」という単語のさまざまな言語が含まれているため、違いを確認できます。
u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
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'))
これがテスト実行です:
>>> u = u'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> 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)
utf-8 b'ABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-8-sig %r' % e8s)
utf-8-sig b'\xef\xbb\xbfABCtest\xce\xb2\xe8\xb2\x9d\xe5\xa1\x94\xec\x9c\x84m\xc3\xa1sb\xc3\xaata|test|\xd8\xa7\xd8\xae\xd8\xaa\xd8\xa8\xd8\xa7\xd8\xb1|\xe6\xb5\x8b\xe8\xaf\x95|\xe6\xb8\xac\xe8\xa9\xa6|\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88|\xe0\xa4\xaa\xe0\xa4\xb0\xe0\xa5\x80\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb7\xe0\xa4\xbe|\xe0\xb4\xaa\xe0\xb4\xb0\xe0\xb4\xbf\xe0\xb4\xb6\xe0\xb5\x8b\xe0\xb4\xa7\xe0\xb4\xa8|\xd7\xa4\xd6\xbc\xd7\xa8\xd7\x95\xd7\x91\xd7\x99\xd7\xa8\xd7\x9f|ki\xe1\xbb\x83m tra|\xc3\x96l\xc3\xa7ek|'
>>> print('utf-16 %r' % e16)
utf-16 b"\xff\xfeA\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16le %r' % e16le)
utf-16le b"A\x00B\x00C\x00t\x00e\x00s\x00t\x00\xb2\x03\x9d\x8cTX\x04\xc7m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x00'\x06.\x06*\x06(\x06'\x061\x06|\x00Km\xd5\x8b|\x00,nf\x8a|\x00\xc60\xb90\xc80|\x00*\t0\t@\t\x15\tM\t7\t>\t|\x00*\r0\r?\r6\rK\r'\r(\r|\x00\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x05|\x00k\x00i\x00\xc3\x1em\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|\x00"
>>> print('utf-16be %r' % e16be)
utf-16be b"\x00A\x00B\x00C\x00t\x00e\x00s\x00t\x03\xb2\x8c\x9dXT\xc7\x04\x00m\x00\xe1\x00s\x00b\x00\xea\x00t\x00a\x00|\x00t\x00e\x00s\x00t\x00|\x06'\x06.\x06*\x06(\x06'\x061\x00|mK\x8b\xd5\x00|n,\x8af\x00|0\xc60\xb90\xc8\x00|\t*\t0\t@\t\x15\tM\t7\t>\x00|\r*\r0\r?\r6\rK\r'\r(\x00|\x05\xe4\x05\xbc\x05\xe8\x05\xd5\x05\xd1\x05\xd9\x05\xe8\x05\xdf\x00|\x00k\x00i\x1e\xc3\x00m\x00 \x00t\x00r\x00a\x00|\x00\xd6\x00l\x00\xe7\x00e\x00k\x00|"
>>> print()
>>> print('utf-8 w/ BOM decoded with utf-8 %r' % e8s.decode('utf-8'))
utf-8 w/ BOM decoded with utf-8 '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-8 w/ BOM decoded with utf-8-sig %r' % e8s.decode('utf-8-sig'))
utf-8 w/ BOM decoded with utf-8-sig 'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16 %r' % e16.decode('utf-16'))
utf-16 w/ BOM decoded with utf-16 'ABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
>>> print('utf-16 w/ BOM decoded with utf-16le %r' % e16.decode('utf-16le'))
utf-16 w/ BOM decoded with utf-16le '\ufeffABCtestβ貝塔위másbêta|test|اختبار|测试|測試|テスト|परीक्षा|പരിശോധന|פּרובירן|kiểm tra|Ölçek|'
両方だけを知って、両方utf-8-sig
とのutf-16
後で元の文字列を取得することは価値がencode
ありdecode
ます。
この問題は基本的に、PythonコードをUTF-8またはUTF-16エンコードで保存するときに発生します。これは、Pythonがコードの先頭に特殊文字を自動的に追加し(テキストエディターでは表示されません)、エンコード形式を識別するためです。ただし、コードを実行しようとすると、PythonコンパイラがASCIIエンコーディングを理解するため、1行目、つまりコードの先頭に構文エラーが表示されます。read()関数を使用してファイルのコードを表示すると、返されたコードの先頭に '\ ufeff'が表示されます。この問題の最も簡単な解決策は、エンコーディングをASCIIエンコーディングに戻すことです。(このため、コードをメモ帳にコピーして保存できます。覚えておいてください!ASCIIエンコーディングを選択してください...これが役立つことを願っています。