我在处理从不同网页(在不同的网站上)获取的文本中的unicode字符时遇到了问题。我用的是BeautifulSoup。

问题是,误差并不总是可再现的;它有时会处理某些页面,有时会通过抛出UnicodeEncodeError而退出。我几乎尝试了我能想到的所有方法,但我没有找到任何能在不引发某种Unicode相关错误的情况下始终工作的方法。

导致问题的代码部分如下所示:

agent_telno = agent.find('div', 'agent_contact_number')
agent_telno = '' if agent_telno is None else agent_telno.contents[0]
p.agent_info = str(agent_contact + ' ' + agent_telno).strip()

下面是运行上面的代码段时在某些字符串上生成的堆栈跟踪:

Traceback (most recent call last):
  File "foobar.py", line 792, in <module>
    p.agent_info = str(agent_contact + ' ' + agent_telno).strip()
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa0' in position 20: ordinal not in range(128)

我怀疑这是因为某些页面(或者更具体地说,来自某些网站的页面)可能是编码的,而其他页面可能是未编码的。所有的网站都设在英国,并提供英国消费的数据,因此不存在与内化或处理非英语文本相关的问题。

有没有人对如何解决这个问题有什么想法,以便我能够始终如一地解决这个问题?


当前回答

在脚本开头添加以下行(或作为第二行):

# -*- coding: utf-8 -*-

这就是python源代码编码的定义。更多信息请参见PEP 263。

其他回答

如果是打印语句的问题,很多时候只是终端打印的问题。这帮助了我:export PYTHONIOENCODING=UTF-8

导致打印失败的一个微妙问题是环境变量设置错误,例如LC_ALL设置为“C”。在Debian中,他们不鼓励设置它:在Locale上设置Debian wiki

$ echo $LANG
en_US.utf8
$ echo $LC_ALL 
C
$ python -c "print (u'voil\u00e0')"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)
$ export LC_ALL='en_US.utf8'
$ python -c "print (u'voil\u00e0')"
voilà
$ unset LC_ALL
$ python -c "print (u'voil\u00e0')"
voilà

下面的解决方案对我有效,刚刚补充

u“字符串”

(表示字符串为unicode)。

result_html = result.to_html(col_space=1, index=False, justify={'right'})

text = u"""
<html>
<body>
<p>
Hello all, <br>
<br>
Here's weekly summary report.  Let me know if you have any questions. <br>
<br>
Data Summary <br>
<br>
<br>
{0}
</p>
<p>Thanks,</p>
<p>Data Team</p>
</body></html>
""".format(result_html)

我找到了一个很好的方法来删除符号并继续将字符串保持为字符串,如下所示:

yourstring = yourstring.encode('ascii', 'ignore').decode('ascii')

需要注意的是,使用忽略选项是危险的,因为它会默默地从使用它的代码中删除任何unicode(和国际化)支持,如下所示(转换unicode):

>>> u'City: Malmö'.encode('ascii', 'ignore').decode('ascii')
'City: Malm'

当django项目使用Apache进行部署时,经常会出现此问题。因为Apache在/etc/sysconfig/httpd中设置了环境变量LANG=C。只需打开文件并对该设置进行注释(或更改为黄色)。或者使用WSGIDaemonProcess命令的lang选项,在这种情况下,您将能够为不同的虚拟主机设置不同的lang环境变量。