2012-01-30 307 views
2

我正在使用亞馬遜MWS API獲取我的商店的銷售報告,然後將該報告保存在數據庫的表中。不幸的是,當我嘗試將信息編碼爲Unicode時,我遇到了編碼錯誤。通過報告(正是因爲亞馬遜送的)看後,我看到這個字符串,它是買家的位置:Python字符串編碼問題

'S�o Paulo'

所以我試圖編碼它像這樣:

encodeme = 'S�o Paulo' 
encodeme.encode('utf-8) 

,但得到的以下錯誤

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

爲什麼我試圖編碼它的全部原因,因爲只要Django的看到字符就拋出了字符串警告,削減,這意味着塔t時的位置被保存爲S,而不是

São Paulo

任何幫助表示讚賞。

回答

3

它看起來像你有某種編碼問題。

首先,你應該非常確定亞馬遜在他們向你發送的報告正文中使用的是什麼編碼。它是UTF-8嗎?是ISO 8859-1嗎?還有別的嗎?

不幸的是,Amazon MWS Reports API documentation,特別是它們的API Reference,並不是非常接近他們使用的編碼。他們只編碼我看到他們提到的是UTF-8,所以這應該是你的第一個猜測。 GetReport API文檔(第36-37頁)將響應元素Report描述爲xs:string,但我沒有看到他們在哪裏定義該數據類型。也許他們的意思是XML Schema's string datatype

所以,我建議你保存從Amazon收到的字節序列作爲你的報告正文在一個文件中,零轉換。請注意,您調用AWS的代碼可能會無意中修改報表主體字符串。用二進制編輯器檢查該文件中的非ASCII字節。 「São」的「São」是否存儲爲S\xC3\xA3o,表示UTF-8編碼?或者它存儲爲S\xE3o,表示ISO 8859-1編碼?

我猜你會收到你的報告作爲一個平面文件。 Amazon AWS文檔說,您可以請求報告以XML形式提供給您。這將有一個明確的編碼聲明給你的答覆。

一旦您知道了報表正文的編碼,您現在需要正確處理它。您意味着您正在使用Django框架和Python語言代碼接收來自Amazon AWS的報告。

一件事變得非常清晰(如Skirmantas也解釋):

  • Unicode字符串持有字符。字節字符串保存字節(八位字節)。
  • 編碼將Unicode字符串轉換爲字節字符串。
  • 解碼將字節字符串轉換爲Unicode字符串。

您從亞馬遜AWS獲得的字符串是字節字符串。你需要解碼它得到一個Unicode字符串。但是,您的代碼片段encodeme = 'São Paulo'爲您提供了一個字節字符串。 encodeme.encode('utf-8)在字節字符串上執行一個encode(),這不是你想要的。 (上'utf-8缺少的結束引號沒有幫助。)

試試這個示例代碼:

>>> reportbody = 'S\xc3\xa3o Paulo' # UTF-8 encoded byte string 
>>> reportbody.decode('utf-8')  # returns a Unicode string, u'...' 
u'S\xe3o Paulo' 

您可能會發現一些背景閱讀很有幫助。我同意Hoxieboy,你應該花時間閱讀Python's Unicode HOWTO。還請查看What do I need to know about Unicode?的最佳答案。

+0

謝謝,我真的很感激它。我會嘗試從亞馬遜獲得xml響應 – Paulo 2012-02-02 23:04:59

1

Official Python unicode documentation

,如果你還沒有,看看你能得到你正在尋找的答案你可以嘗試的網頁;)

+0

應該是一個評論 – 2012-01-30 07:40:12

+0

應該看看我在哪裏發帖,D'哦!我是新來的,如果你還沒有注意到:) – CR0SS0V3R 2012-01-30 07:54:41

+0

不用擔心!有答案的問題會得到較少的關注,所以如果絕對不是答案,那只是禮儀。 – 2012-01-30 07:58:09

4

我認爲你必須使用正確的編碼進行解碼而不是將其編碼爲utf-8。嘗試

s = s.decode('utf-8') 

但是,您需要知道使用哪種編碼。輸入可以用utf-8編碼。

您收到的錯誤UnicodeDecodeError表示您的對象不是unicode,它是一個字節串。當您執行bytestring.encode時,首先使用默認編碼(ascii)將字符串解碼爲unicode對象,然後才使用utf-8對其進行編碼。

我會嘗試解釋python中unicode stringutf-8 bytestring的區別。

unicode是表示unicode字符串的python數據類型。您的程序中大部分字符串操作都使用unicode。 Python可能在其內部使用utf-8,儘管它也可能是utf-16,這對你並不重要。

bytestring是一個二進制安全字符串。它可以是任何編碼。當你接收到數據時,例如你打開一個文件,你會得到一個字節串,在大多數情況下,你會想將它解碼爲unicode。在寫入文件時,必須將unicode對象編碼爲字節串。有時解碼/編碼是由框架或庫爲您完成的。然而,並不總是框架可以這樣做,因爲並不總是框架可以知道使用哪種編碼。

utf-8是一種可以正確表示任何unicode字符串作爲字符串的編碼。但是你不能用utf-8將任何種類的字符串解碼爲unicode。你需要知道在字節串中使用什麼編碼來解碼它。