2013-07-28 110 views
46

我得到以下圖案的錯誤:U「 ufeff」在Python字符串

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

不知道什麼u'\ufeff'是,它顯示了當我網頁抓取。我該如何糾正這種情況?字符串方法.replace()不適用於它。

+5

這個輸入來自哪裏?你想做什麼?請包含您的Python代碼。 – 2013-07-28 20:03:33

+1

順便說一句,如果我記得unicode指示符,我發現.replace()在現代python中工作:s.replace(u'\ ufeff','') –

+0

@DougBradshaw當你說「現代python」時,你的意思是,2.7+還是3.0+? – teewuane

回答

78

Unicode字符U+FEFF是字節順序標記或BOM,用於說明大端和小端UTF-16編碼之間的區別。如果您使用正確的編解碼器解碼網頁,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不會知道,如果數據是大端或小端。

2

該字符是BOM或「字節順序標記」。它通常作爲文件的前幾個字節接收,告訴你如何解釋其餘數據的編碼。你可以簡單地刪除角色繼續。雖然,由於錯誤表示您正在嘗試轉換爲'ascii',所以您應該爲您嘗試執行的任何操作選擇另一種編碼。

-1

具體的feff字節順序標記是UTF-16編碼的一個指標。由於很少使用utf-16的所有字節,因此人們使用兩種不同的編碼方案。由於不同的編碼基本上只是翻轉utf-16中的字節,因此標準是字節順序標記始終爲feff。這樣,如果有人用字節順序標記發送了某個字節,則unicode編碼器知道翻轉隨後文檔中所有字節的順序。

+0

'UTF-16'有兩種不同的編碼:小端和大端。字節順序標記用於說明差異。 –

+2

您正在描述UTF-16。 「字節順序」在utf-8中與*不相關,因爲按照定義它只使用8位代碼。因此FEFFh永遠不可能是一個有效的UTF-8代碼。它的8位*表示*可以(它是3個字節長),但是隻有在解析成Unicode字符後纔可以。然後你不再對像「字節排序」這樣的低層次感興趣。在其他有效的UTF-8文件的開始處查找0FEFFh(以UTF8編碼)可能是編碼錯誤,並且可以安全地忽略。 – usr2564301

4

你刮的內容以Unicode進行編碼,而不是ASCII文本,和你得到的是不轉換爲ASCII字符。正確的'翻譯'取決於原始網頁的想法。 Python's unicode page給出了它如何工作的背景。

你想要打印結果還是將其粘貼到文件中?錯誤表明它是寫入導致問題的數據,而不是讀取它。 This question是查找修復程序的好地方。

1

此問題出現基本上當您保存Python代碼在UTF-8或UTF-16編碼因爲Python在自動的代碼(這不是由文本編輯器中所示)的開頭添加一些特殊字符識別編碼格式。但是,當您嘗試執行代碼時,它會爲您提供第1行的語法錯誤,即代碼開始,因爲python編譯器理解ASCII編碼。 當查看使用讀取的文件的代碼()函數你可以在開始返回代碼的看到「\ ufeff」示出爲。 解決這個問題的一個簡單的解決方案是隻是改變編碼回ASCII編碼(此您可以將代碼複製到記事本並保存它記住!選擇ASCII編碼... 希望這會有所幫助。

0

我在Python 3上遇到了這個問題,並且發現了這個問題(和solution)。 打開文件時,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美分。