【问题标题】:Decoding UTF-8 URL in Python在 Python 中解码 UTF-8 URL
【发布时间】:2012-08-13 17:28:11
【问题描述】:

我有一个类似“pe%20to%C5%A3i%20mai”的字符串。当我对其应用 urllib.parse.unquote 时,我得到“pe to\u0163i mai”。如果我尝试将其写入文件,我会得到那些确切的符号,而不是预期的字形。

如何将字符串转换为 utf-8,以便在文件中使用正确的字形?

编辑:我使用的是 Python 3.2

Edit2:所以我发现urllib.parse.unquote 工作正常,而我的问题实际上是我正在使用yaml.dump 序列化为YAML,这似乎把事情搞砸了。为什么?

【问题讨论】:

  • 听起来像是代码中的错误。你能发布你的代码吗?
  • 你在这里做了很多事情。您正在 1) 在程序中编写字符串文字,2) 使用库函数对其进行解码,3) 将其写入文件,4) 从文件中读取并 5) 打印它。在这些步骤中的每一个步骤中都存在字符编码问题。如果任何一个步骤包含错误,则最终结果将是错误的。与其一次做 5 件事,不如将你的问题分解为五个较小的问题。测试每一步都发生了正确的事情。检查中间结果。确定五个步骤中的哪一个是行不通的。并发布您的代码。

标签: python utf-8 python-3.x yaml urldecode


【解决方案1】:

更新:如果输出文件是 yaml 文档,那么您可以忽略其中的 \u0163。 Unicode 转义在 yaml 文档中有效。

#!/usr/bin/env python3
import json

# json produces a subset of yaml
print(json.dumps('pe toţi mai')) # -> "pe to\u0163i mai"
print(json.dumps('pe toţi mai', ensure_ascii=False)) # -> "pe toţi mai"

注意:在最后一种情况下没有\u。这两行代表同一个 Python 字符串。

yaml.dump() 有类似的选项:allow_unicode。将其设置为 True 以避免 Unicode 转义。


网址正确。你不需要对它做任何事情:

#!/usr/bin/env python3
from urllib.parse import unquote

url =  "pe%20to%C5%A3i%20mai"
text = unquote(url)

with open('some_file', 'w', encoding='utf-8') as file:
    def p(line):
        print(line, file=file) # write line to file

    p(text)                # -> pe toţi mai
    p(repr(text))          # -> 'pe toţi mai'
    p(ascii(text))         # -> 'pe to\u0163i mai'

    p("pe to\u0163i mai")  # -> pe toţi mai
    p(r"pe to\u0163i mai") # -> pe to\u0163i mai
    #NOTE: r'' prefix

\u0163 序列可能由字符编码错误处理程序引入:

with open('some_other_file', 'wb') as file: # write bytes
    file.write(text.encode('ascii', 'backslashreplace')) # -> pe to\u0163i mai

或者:

with open('another', 'w', encoding='ascii', errors='backslashreplace') as file:
    file.write(text) # -> pe to\u0163i mai

更多示例:

# introduce some more \u escapes
b = r"pe to\u0163i mai ţţţ".encode('ascii', 'backslashreplace') # bytes
print(b.decode('ascii')) # -> pe to\u0163i mai \u0163\u0163\u0163
# remove unicode escapes
print(b.decode('unicode-escape')) # -> pe toţi mai ţţţ

【讨论】:

    【解决方案2】:

    使用unicode_escape 尝试decode

    例如:

    >>> print "pe to\u0163i mai".decode('unicode_escape')
    pe toţi mai
    

    【讨论】:

    • 上面写着AttributeError: 'str' object has no attribute 'decode'
    【解决方案3】:

    Python 3

    调用 urllib.parse.unquote 已经返回一个 Unicode 字符串:

    >>> urllib.parse.unquote("pe%20to%C5%A3i%20mai")
    'pe toţi mai'
    

    如果你没有得到这个结果,那一定是你的代码有错误。请发布您的代码。

    Python 2

    使用decode从字节串中获取Unicode字符串:

    >>> import urllib2
    >>> print urllib2.unquote("pe%20to%C5%A3i%20mai").decode('utf-8')
    pe toţi mai
    

    请记住,当您将 Unicode 字符串写入文件时,您必须再次对其进行编码。您可以选择以 UTF-8 格式写入文件,但如果您愿意,也可以选择不同的编码。您还必须记住在从文件中读取时使用相同的编码。您可能会发现codecs 模块对于在读取和写入文件时指定编码很有用。

    >>> import urllib2, codecs
    >>> s = urllib2.unquote("pe%20to%C5%A3i%20mai").decode('utf-8')
    
    >>> # Write the string to a file.
    >>> with codecs.open('test.txt', 'w', 'utf-8') as f:
    ...     f.write(s)
    
    >>> # Read the string back from the file.
    >>> with codecs.open('test.txt', 'r', 'utf-8') as f:
    ...     s2 = f.read()
    

    一个可能令人困惑的问题是,在交互式解释器中,Unicode 字符串有时使用\uxxxx 表示法而不是实际字符来显示:

    >>> s
    u'pe to\u0163i mai'
    >>> print s
    pe toţi mai
    

    这并不意味着字符串是“错误的”。这就是解释器的工作方式。

    【讨论】:

    【解决方案4】:

    urllib.parse.unquote 返回了正确的 UTF-8 字符串,并将其直接写入返回的文件中得到了预期的结果。问题出在 yaml 上。默认情况下,它不使用 UTF-8 编码。

    我的解决方案是:

    yaml.dump("pe%20to%C5%A3i%20mai",encoding="utf-8").decode("unicode-escape")

    感谢 J.F. Sebastian 和 Mark Byers 向我提出了正确的问题,帮助我解决了问题!

    【讨论】:

    • 我会用的。下次我会更仔细阅读yaml文档:))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-10
    • 2012-10-18
    • 2019-09-15
    相关资源
    最近更新 更多