Python、.format() 和 UTF-8

标签 python unicode beautifulsoup

我的背景是 Perl,但我正在为一个新项目尝试 Python 和 BeautifulSoup。

在这个例子中,我试图提取并呈现单个页面中包含的链接目标和链接文本。这是来源:

table_row = u'<tr><td>{}</td><td>{}</td></tr>'.encode('utf-8')
link_text = unicode(link.get_text()).encode('utf-8')
link_target = link['href'].encode('utf-8')
line_out = unicode(table_row.format(link_text, link_target))

所有这些对 .encode('utf-8') 的显式调用都是我为使这项工作起作用而进行的尝试,但它们似乎无济于事——很可能我完全误解了 Python 2.7 如何处理 Unicode字符串。

无论如何。直到它在 URL 中遇到 U+2013(是的,真的)之前,它都可以正常工作。在那一点上,它爆炸了:

Traceback (most recent call last):
File "./test2.py", line 30, in <module>
  line_out = unicode(table_row.encode('utf-8').format(link_text, link_target.encode('utf-8')))
  UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 79: ordinal not in range(128)

据推测,即使应用于 Unicode 字符串的 .format() 也是在耍傻,并试图执行 .decode() 操作。由于 ASCII 是默认的,它正在使用它,当然它不能将 U+2013 映射到 ASCII 字符,因此......

选项似乎是将其删除或将其转换为其他内容,但我真正想要的是简单地保留它。最终(这只是一个小测试用例)我需要能够呈现有效的可点击链接。

BS3 文档建议将默认编码从 ASCII 更改为 UTF-8,但阅读类似问题的评论看起来是一个非常糟糕的主意,因为它会弄乱字典。

如果不使用 Python 3.2(这意味着没有 Django,我们正在考虑将其作为该项目的一部分)是否有某种方法可以使这项工作干净利落?

最佳答案

首先,请注意您的两个代码示例在有问题的行的文本上存在分歧:

line_out = unicode(table_row.encode('utf-8').format(link_text, link_target.encode('utf-8')))

对比

line_out = unicode(table_row.format(link_text, link_target))

第一个是回溯中的那个,所以它是要看的那个。假设您的第一个代码示例的其余部分是准确的,table_row 是一个字节字符串,因为您采用了一个 unicode 字符串并对其进行了编码。无法对字节字符串进行编码,因此 Python 2 通过将其解码为 ascii,将 table_row 从字节字符串隐式转换为 unicode。因此出现错误消息“来自 ascii 的 UnicodeDecodeError”。

您需要决定哪些字符串是字节字符串,哪些是 unicode 字符串,并对此加以规范。我建议尽可能将所有文本保留为 Unicode 字符串。

这是我在 PyCon 上的一个演示文稿,解释了这一切:Pragmatic Unicode, or, How Do I Stop The Pain?

关于Python、.format() 和 UTF-8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11007709/

相关文章:

python - 复制内置类

c++ - 如何正确跳过 unicode (UTF-8) 字符?

python - 使用 Beautiful Soup 查找第三个出现的 `<p>` 标签

python - BeautifulSoup 找不到具有特定类的 div

python - 文件相关操作 python 子进程 vs 原生 python

python - 从 settings.py 文件中提取密码

python - 屏蔽 numpy 数组中的圆形扇区

c++ - 将 STL unicode 字符串转换为 wxString 给出空字符串

php - 替换unicode字符

python - 根据 Beautifulsoup 中的内容排除标签