UnicodeEncodeError: 'ascii' 编解码器无法对位置 20 中的字符 u'\xa0' 进行编码:序号不在 range(128)

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

问题是错误并不总是可重现的;它有时适用于某些页面,有时,它通过抛出.我已经尝试了我能想到的几乎所有东西,但我没有找到任何可以一致工作的东西,而不会抛出某种与Unicode相关的错误。UnicodeEncodeError

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

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

你需要阅读Python Unicode HOWTO。此错误是第一个示例

基本上,停止使用以从unicode转换为编码的文本/字节。str

相反,请正确使用 .encode() 对字符串进行编码:

p.agent_info = u' '.join((agent_contact, agent_telno)).encode('utf-8').strip()

或完全使用 Unicode。


答案 2

这是一个经典的python unicode痛点!请考虑以下事项:

a = u'bats\u00E0'
print a
 => batsà

到目前为止一切都很好,但是如果我们调用str(a),让我们看看会发生什么:

str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe0' in position 4: ordinal not in range(128)

哦,蘸酱,这对任何人都没有好处!要修复此错误,请使用 .encode 显式编码字节,并告诉 python 要使用的编解码器:

a.encode('utf-8')
 => 'bats\xc3\xa0'
print a.encode('utf-8')
 => batsà

瞧\u00E0!

问题是,当你调用str()时,python使用默认字符编码来尝试和编码你给它的字节,在你的情况下,这些字节有时是unicode字符的表示形式。要解决这个问题,你必须告诉python如何处理你使用.encode('whatever_unicode')给出的字符串。大多数时候,你应该可以使用utf-8。

有关此主题的精彩阐述,请参阅Ned Batchelder的PyCon演讲:http://nedbatchelder.com/text/unipain.html