2012-01-30 182 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。你需要知道在字节串中使用什么编码来解码它。