我正在使用我用Python编写的客户端从Web服务中检索名称列表。检索列表后,我将每个名称编码为unicode,然后将每个名称打印到stdout。当我得到“ÓlafurJóhannÓlafsson”这个名字时,我收到以下错误:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0:
ordinal not in range(128)
由于我不知道编码是什么,如何将所有这些字符串转换为unicode?或者你能建议一个更好的方法来处理这个问题吗?
答案 0 :(得分:1)
来自BeautifulSoup
的UnicodeDammit
模块可以自动检测编码。
from BeautifulSoup import UnicodeDammit
u = UnicodeDammit("Ólafur Jóhann Ólafsson")
print u.unicode
print u.originalEncoding
答案 1 :(得分:1)
此页面可能会对您有所帮助http://wiki.python.org/moin/PrintFails
问题,我想,你需要将这些名称打印到控制台。你真的需要它吗?或者它只是一个测试环境?如果您仅使用控制台进行测试,您可以切换到其他工具,如单元测试,以检查您确切获得的值。
答案 2 :(得分:1)
首先,从文件,管道,套接字,终端等读取时,解码数据到Unicode(编码的缺席);发送/保存数据时,将编码 Unicode编码为适当的字节编码。我怀疑这是你问题的根源。
Web服务应在收到的标头或数据中声明编码。 print
通常会自动将Unicode编码为终端的编码(通过sys.stdout.encoding
发现)或仅在ascii
时没有编码。如果目标编码不支持数据中的字符,您将获得UnicodeEncodeError
。
由于这不是您收到的错误,您应该发布一些代码,以便我们可以看到您在做什么。最有可能的是,您编码一个字节字符串而不是解码。这是一个例子:
>>> data = '\xc2\xbd' # UTF-8 encoded 1/2 symbol.
>>> data.encode('cp437')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\dev\python\lib\encodings\cp437.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 0: ordinal not in range(128)
我在这里做的是在字节字符串上调用encode
。由于encode
需要Unicode字符串,因此在编码为ascii
之前,Python首先使用默认的cp437
编码将字节字符串解码为Unicode。
通过解码而不是编码数据来解决此问题,然后print
将自动编码为stdout。只要您的终端支持数据中的字符,它就会正确显示:
>>> import sys
>>> sys.stdout.encoding
'cp437'
>>> print data.decode('utf8') # implicit encode to sys.stdout.encoding
½
>>> print data.decode('utf8').encode('cp437') # explicit encode.
½