2010-09-06 30 views
1

我使用我用Python編寫的客戶端從Web服務中檢索名稱列表。在檢索列表時,我將每個名稱都編碼爲unicode,然後將它們打印到標準輸出。當我到了名爲「奧拉夫爾·約翰·奧拉夫森」,我得到以下錯誤:當我無法預先知道字符編碼時,如何打印字符串列表?

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: 
        ordinal not in range(128) 

因爲我不知道該編碼將是什麼,我如何將所有這些字符串爲Unicode?或者你能否提出一個更好的方法來處理這個問題?

+0

Web服務不會告訴您其標頭中的編碼嗎? – 2010-09-06 16:28:04

+0

你確定你不知道編碼是什麼嗎?如果是這樣,那是由於Web服務的糟糕設計。你能解決這個問題嗎?或讓其他人修復它? – 2010-09-06 16:28:31

+0

我也將探索web服務的編碼。謝謝。 – kobrien 2010-09-07 19:55:21

回答

1

首先,你解碼數據爲Unicode(所述沒有編碼的)從一個文件,管道,套接字終端讀出時,等;和編碼 Unicode發送/持久數據時適當的字節編碼。我懷疑這是你問題的根源。

Web服務應該在收到的頭文件或數據中聲明編碼。 print通常會自動將Unicode編碼爲終端的編碼(通過sys.stdout.encoding發現)或僅在ascii的情況下編碼。如果數據中的字符不受目標編碼支持,您將獲得UnicodeEncodeError

既然這不是你收到的錯誤,你應該發佈一些代碼,以便我們可以看到你在做什麼。最有可能的是,你是編碼一個字節字符串而不是解碼。這裏有這樣一個例子:

>>> data = '\xc2\xbd' # UTF-8 encoded 1/2 symbol. 
>>> data.encode('cp437') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "C:\dev\python\lib\encodings\cp437.py", line 12, in encode 
    return codecs.charmap_encode(input,errors,encoding_map) 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128) 

我在這裏做什麼是一個字節的字符串調用encode。由於encode需要一個Unicode字符串,因此Python使用默認的ascii編碼將字節字符串解碼爲Unicode,然後編碼爲cp437

通過解碼解決這個問題,而不是編碼數據,然後print將自動編碼爲標準輸出。只要您的終端支持數據中的字符,它就會正確顯示:

>>> import sys 
>>> sys.stdout.encoding 
'cp437' 
>>> print data.decode('utf8') # implicit encode to sys.stdout.encoding 
½ 
>>> print data.decode('utf8').encode('cp437') # explicit encode. 
½ 
1

BeautifulSoupUnicodeDammit模塊可以自動檢測編碼。

from BeautifulSoup import UnicodeDammit 

u = UnicodeDammit("Ólafur Jóhann Ólafsson") 

print u.unicode 
print u.originalEncoding 
+0

這太好了。謝謝。我會允許一段時間讓更多人回答,但是這聽起來像是可以做到的。 – kobrien 2010-09-06 16:13:44

1

此頁面可以幫助你http://wiki.python.org/moin/PrintFails

的問題,我想,是你需要打印這些名字來安慰。你真的需要它嗎?或者它只是一個測試環境?如果您只是爲了測試而使用控制檯,則可以切換到其他工具(如單元測試)以檢查您準確獲取的值。