【问题标题】:Python UTF-8 encoding wrong representationPython UTF-8 编码错误表示
【发布时间】:2015-11-12 16:10:16
【问题描述】:

我正在使用 python 2.7.X。我加载了一些 XML,XML 是 utf-8 编码的。所以我做了以下事情:

def get_xml(self):
    r = requests.get("https://dataserver.com")
    xml = r.text
    return xml.encode("utf-8")

def parse_xml(xml):
    tree = ET.fromstring(xml)
    for child in tree:
        print "    Raw type = " + str(type(child.attrib["name"]))
        print "Encoded type = " + str(type(child.attrib["name"].encode("utf-8")))
        print child.attrib["name"].encode("utf-8")
        print str(child.attrib["name"])
        print "------------"

这会导致以下错误:

    Raw type = <type 'unicode'>
Encoded type = <type 'str'>
Malmö FF - Paris SG
Traceback (most recent call last):
...
UnicodeEncodeError: 'ascii' codec can't encode characters in position 4-5: ordinal not in range(128)

所以,UnicodeEncodeError 对我来说很清楚。但是,在将unicodestring 编码为utf-8string 之后,我希望它能够正确表示。也就是说,Malmö FF 实际上应该是Malmö FF

我在这里做错了什么?

【问题讨论】:

    标签: python encoding utf-8


    【解决方案1】:

    我认为您的表达式 str(child.attrib["name"]) 将使用标准编码来编码 unicode。你确定这是设置为 utf-8 吗?我的猜测是您将其设置为 latin-1 或其他内容。尝试将其重写为child.attrib["name"].encode("utf-8")

    【讨论】:

    • 感谢您的建议。但是,我 100% 确定它是 UTF-8。 print "Latin-1 Encoded type = " + str(type(child.attrib["name"].encode("latin-1"))) 也会导致错误。
    • 当你已经编码了一些东西时,你不需要转换为str。它将是具有特定编码的字节串。我仍然建议您尝试我建议的重写,以确保。
    • 您确定您的建议没有错字吗?你建议child.attrib["name"].encode("utf-8")。我已经这样做了
    • 好吧,你是对的。它确实是latin-1 编码的。这很奇怪,因为 xml 编码被明确设置为 utf-8
    • 我的意思是for child in tree 循环中的第四个print。它没有被编码,并且在你转换str之前将是unicode,然后python会尝试将它编码为默认的任何编码。在你的情况下 latin-1.
    【解决方案2】:

    你有很多问题:

    1. 您要么在 Windows 上,要么使用不正确的终端仿真连接到 Unix 机器。您的终端错误地将一个多字节 UTF-8 字符转换为两个 ISO-8895-* 字符:

      Malmö 在 Windows-1252/ISO-8895-* 中 = Malm\xc3\xb6 = Malmö 在 UTF-8 中。

    2. 如果您使用的是 Windows,请不要将 UTF-8 打印到控制台。使用这个:https://github.com/Drekin/win-unicode-console

    3. 打印前不要编码。让 Python 为你做这件事。如果 Python 抱怨并且您使用的是 Unix,请确保您的语言环境设置为 UTF-8 版本,例如en_US.UTF-8。如果一切都失败了,请在您的环境中设置PYTHONIOENCODING=UTF-8

    4. 除非你真的必须,否则不要将 Unicode 对象转换为 str 对象。如果这样做,请使用.encode("utf-8") 而不是str()(它们的结果都是str 对象)以确保使用合适的编码。但再说一遍 - 不要这样做。

    5. 如果您需要将 Unicode 对象转换为文件,请使用:

      my_f = io.open("myfile.txt", "w", encoding="utf-8")
      my_f.write(my_unicode_object)
      

      将为您编码 Unicode 对象。

    【讨论】:

    • 感谢您提出的意见。仅供参考:我正在使用带有标准 Apple 终端应用程序的 Mac OS X Yosemite。我的语言环境都设置为包含UTF-8 的内容。我还是不明白为什么这些字符串是用 latin-1 编码的?
    • Apple 终端具有仿真设置。它应该设置为 UTF-8,但可能已更改。转到“首选项”->“配置文件”->“高级”。记得不要再打电话给.encode()str()
    • 嗯,终端设置为 UTF-8
    • 如果我将仿真错误地设置为“Windows-1252”,我可以复制Malmö。如果您删除 .encode() ,它仍然会这样做吗?
    • 好吧,我的终端设置为 UTF-8,print "Without str() or encoding(...): " + child.attrib["name"] 的输出是Without str() or encoding(...): Malmö FF - Paris SG
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2018-01-14
    相关资源
    最近更新 更多