UnicodeEncodeError: 'ascii'编解码器无法在第20个位置编码字符u'\xa0',该位置的序数不在128范围内。

1495
我在处理从不同网页(不同网站)获取的文本时遇到了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)

我怀疑这是因为有些页面(或更具体地说,来自某些网站的页面)可能被编码,而其他页面可能没有编码。所有网站都位于英国,提供的数据面向英国市场 - 因此不存在与国际化或处理非英语文本相关的问题。

有没有人有任何想法如何解决这个问题,以便我可以一致地修复它?


1
如果您作为用户而不是开发人员遇到这些错误,请查看 https://serverfault.com/questions/54591/how-to-install-change-locale-on-debian 和 https://askubuntu.com/questions/599808/cannot-set-lc-ctype-to-default-locale-no-such-file-or-directory。 - That Brazilian Guy
4
尝试使用以下代码:import os; import locale; os.environ["PYTHONIOENCODING"] = "utf-8"; myLocale=locale.setlocale(category=locale.LC_ALL, locale="en_GB.UTF-8"); ... print(myText.encode('utf-8', errors='ignore')) - hhh
@hhh,我运行了你的代码片段,出现了NameError: name 'myText' is not defined的错误。 - KHAN irfan
27
在执行脚本之前,尝试在shell中设置PYTHONIOENCODING$ export PYTHONIOENCODING=utf8 - Noam Manos
在我的情况下,字符串是 - u'1d6f4975842f050bf6503b19250d09f997b34f4a\n',我只是在同一字符串上使用了.encode('utf-8').strip()。它的作用是从字符串中删除最后一个\n,这之前会出现问题,即使之前使用了encode('utf-8')。 - Indrajeet Gour
34个回答

5
以下解决方案对我有效,只需在我的字符串之前添加u"String"(将字符串表示为Unicode)即可。
示例代码: ```

u "字符串"

```
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)

5
在写这个不支持编码的字符串(例如 data_that_causes_this_error)到某个文件(如results.txt)的一般情况下,它可以正常工作。
f = open("results.txt", "w")
  f.write(data_that_causes_this_error.encode('utf-8'))
  f.close()

4
我刚遇到了这个问题,谷歌将我带到了这里,为了补充一下这里的解决方案,这是对我有效的方法:
# 'value' contains the problematic data
unic = u''
unic += value
value = unic

在阅读Ned的演讲后,我有了这个想法。

尽管如此,我并不完全理解为什么它有效。因此,如果有人可以编辑这个答案或发表评论来解释一下,我将不胜感激。


3
在此之前和之后,变量'value'的'type'是什么?我认为这能起作用的原因是通过执行unic += value(与unic = unic + value相同),你正在添加一个字符串和一个Unicode,Python会假定更精确的类型即所得到的'unic'是unicode(想想当你执行a = float(1) + int(1)时,‘a’变成了float类型),然后value = unic将'value'指向新的unic对象,该对象恰好是unicode。 - Tom Myddeltyn

4
推荐的解决方案对我没有用,我可以接受删除所有非ASCII字符,因此
s = s.encode('ascii',errors='ignore')

这让我得到了一个已剥离的东西,不会出现错误。


4
我们在使用本地化数据时,在Django中运行manage.py migrate时遇到了这个错误。
我们的源代码包含# -*- coding: utf-8 -*-声明,MySQL已正确配置为utf8,并且Ubuntu在/etc/default/locale中具有适当的语言包和值。
问题很简单,就是Django容器(我们使用docker)缺少LANG环境变量。
LANG设置为en_US.UTF-8,并在重新运行迁移之前重启容器即可解决问题。

4

3

许多答案(例如@agf和@Andbdrew)已经解决了OP问题的大部分方面。

然而,我认为有一个微妙但重要的方面被忽略了,对于像我一样在尝试理解Python编码时来到这里的人来说非常重要:Python 2与Python 3管理字符表示方式的方式截然不同。我觉得混淆的大部分原因都是因为人们在没有意识到版本差异的情况下阅读有关Python编码的文章。

我建议任何想要了解OP问题根本原因的人首先阅读Spolsky关于字符表示和Unicode的介绍,然后再阅读Batchelder关于Python 2和Python 3中的Unicode。


是的,我的错误出在 Python 2.7 上,'a'.format(u'ñ')。正确的解决方案不是使用 .encode('utf-8'),而是始终使用 Unicode 字符串(Python 3 的默认设置):u'a'.format(u'ñ')。 - Rogelio Triviño

3

尽量避免将变量转换为str(variable)。有时,这可能会导致问题。

避免的简单技巧:

try: 
    data=str(data)
except:
    data = data #Don't convert to String

上述示例还可以解决编码错误。

这样做是行不通的,因为你只会在 except 中遇到错误。 - Aurele Collinet

1

在运行脚本之前,您可以将字符编码设置为UTF-8

export LC_CTYPE="en_US.UTF-8"

这通常可以解决问题。

1
如果你有类似于packet_data = "This is data"的东西,那么在初始化packet_data后的下一行,做如下操作:
unic = u''
packet_data = unic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接