Python:UnicodeEncodeError:'latin-1' 编码无法编码字符
我遇到了一个情况,我调用一个API,然后根据API返回的结果,再去数据库查询每一条记录。我的API调用返回的是字符串,当我根据API返回的内容去数据库查询时,有些元素出现了以下错误。
Traceback (most recent call last):
File "TopLevelCategories.py", line 267, in <module>
cursor.execute(categoryQuery, {'title': startCategory});
File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/cursors.py", line 158, in execute
query = query % db.literal(args)
File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 265, in literal
return self.escape(o, self.encoders)
File "/opt/ts/python/2.7/lib/python2.7/site-packages/MySQLdb/connections.py", line 203, in unicode_literal
return db.literal(u.encode(unicode_literal.charset))
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 3: ordinal not in range(256)
上面提到的错误是我代码中的这一部分:
...
for startCategory in value[0]:
categoryResults = []
try:
categoryRow = ""
baseCategoryTree[startCategory] = []
#print categoryQuery % {'title': startCategory};
cursor.execute(categoryQuery, {'title': startCategory}) #unicode issue
done = False
cont...
我在网上搜索了一下,尝试在命令行上执行以下操作,以了解发生了什么……
>>> import sys
>>> u'\u2013'.encode('iso-8859-1')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u2013' in position 0: ordinal not in range(256)
>>> u'\u2013'.encode('cp1252')
'\x96'
>>> '\u2013'.encode('cp1252')
'\\u2013'
>>> u'\u2013'.encode('cp1252')
'\x96'
但是我不确定如何解决这个问题。此外,我也不知道encode('cp1252')
背后的原理,如果能对我上面尝试的内容做一些解释就太好了。
3 个回答
1
u.encode('utf-8')
这个操作会把字符串转换成字节,这样就可以通过 sys.stdout.buffer.write(bytes)
将这些字节打印到标准输出上。你可以查看关于显示钩子的详细信息,链接在这里:https://docs.python.org/3/library/sys.html
3
unicode字符u'\02013'代表的是“短破折号”。这个字符在Windows-1252(也叫cp1252)字符集中是有的,编码是x96,但在Latin-1(iso-8859-1)字符集中是没有的。Windows-1252字符集在x80到x9f的范围内还有一些其他字符,其中就包括短破折号。
解决这个问题的方法是选择一个不同的目标字符集,比如Windows-1252或者UTF-8,或者把短破折号换成一个简单的“-”。
24
如果你需要使用拉丁-1编码,有几种方法可以去掉短横线或者其他大于255的字符(这些字符不在拉丁-1编码里):
>>> u = u'hello\u2013world'
>>> u.encode('latin-1', 'replace') # replace it with a question mark
'hello?world'
>>> u.encode('latin-1', 'ignore') # ignore it
'helloworld'
或者你可以自己做一些自定义的替换:
>>> u.replace(u'\u2013', '-').encode('latin-1')
'hello-world'
如果你不一定要输出拉丁-1编码,那么UTF-8是一个常见且更受欢迎的选择。W3C推荐使用UTF-8,它可以很好地编码所有的Unicode字符:
>>> u.encode('utf-8')
'hello\xe2\x80\x93world'