【问题标题】:Python string encoding issuePython字符串编码问题
【发布时间】:2012-02-22 01:16:42
【问题描述】:

我正在使用亚马逊 MWS API 获取我的商店的销售报告,然后将该报告保存在数据库的表中。不幸的是,当我尝试将信息编码为 Unicode 时出现编码错误。在查看报告后(与亚马逊发送的完全一样),我看到了这个字符串,它是买家的位置:

“圣保罗”

所以我尝试像这样对其进行编码:

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

但出现以下错误

UnicodeDecodeError:“ascii”编解码器无法解码位置 1 的字节 0xef:序数不在范围内 (128)

我尝试对其进行编码的全部原因是因为一旦 Django 看到 字符,它就会抛出警告并切断字符串,这意味着该位置被保存为 S 而不是

圣保罗

感谢任何帮助。

【问题讨论】:

    标签: python django unicode encoding


    【解决方案1】:

    您似乎遇到了某种编码问题。

    首先,您应该非常确定亚马逊在他们发送给您的报告正文中使用了什么编码。是 UTF-8 吗?是 ISO 8859-1 吗?还有什么?

    不幸的是,Amazon MWS Reports API documentation,尤其是他们的API Reference,对于他们使用的编码方式并不是很坦率。他们唯一的编码我看到他们提到的是UTF-8,所以这应该是你的第一个猜测。 GetReport API 文档 (p.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编码?

    我猜您收到的报告是一个平面文件。亚马逊 AWS 文档说您可以请求以 XML 格式将报告交付给您。这样做的好处是给你一个带有显式编码声明的回复。

    知道报告正文的编码后,您现在需要正确处理它。您暗示您正在使用 Django 框架和 Python 语言代码来接收来自 Amazon AWS 的报告。

    有一点要弄清楚(正如 Skirmantas 也解释的那样):

    • Unicode 字符串包含字符。字节字符串包含字节(八位字节)。
    • 编码 将 Unicode 字符串转换为字节字符串。
    • 解码 将字节字符串转换为 Unicode 字符串。

    您从 Amazon AWS 获得的字符串是一个 byte 字符串。您需要对其进行解码 以获取 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? 的热门答案。

    【讨论】:

    • 谢谢,我真的很感激。我将尝试从亚马逊获取 xml 响应
    【解决方案2】:

    我认为您必须使用正确的编码对其进行解码,而不是将其编码为 utf-8。试试

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

    但是,您需要知道要使用哪种编码。输入可以采用 utf-8 的其他编码。

    您收到的错误UnicodeDecodeError 表示您的对象不是 unicode,它是一个字节串。当您执行bytestring.encode 时,首先将字符串解码为具有默认编码(ascii)的 unicode 对象,然后才使用 utf-8 进行编码。

    我将尝试解释unicode stringutf-8 bytestring在python中的区别。

    unicode 是 python 的数据类型,表示 unicode 字符串。程序中的大多数字符串操作都使用 unicode。 Python 可能在其内部使用 utf-8,尽管它也可能是 utf-16,这对你来说并不重要。

    bytestring 是一个二进制安全字符串。它可以是任何编码。当你接收数据时,例如你打开一个文件,你会得到一个字节串,在大多数情况下你会想要将它解码为 un​​icode。当您写入文件时,您必须将 unicode 对象编码为字节串。有时解码/编码是由框架或库为您完成的。然而,框架并不总是可以做到这一点,因为框架并不总是知道要使用哪种编码。

    utf-8 是一种可以正确地将任何 unicode 字符串表示为字节串的编码。但是,您不能使用 utf-8 将任何类型的字节串解码为 un​​icode。您需要知道字节串中使用什么编码来解码它。

    【讨论】:

      【解决方案3】:

      Official Python unicode documentation

      如果您还没有尝试过该网页,您可以尝试一下,看看能否得到您正在寻找的答案;)

      【讨论】:

      • 应该看看我发帖的地方,D'oh!如果您还没有注意到,我是新人:)
      • 别担心!有答案的问题很少受到关注,所以如果它绝对不是答案,这只是一种很好的礼仪。
      猜你喜欢
      • 2014-01-08
      • 2020-04-04
      • 1970-01-01
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-17
      相关资源
      最近更新 更多