正如 bernie 所指出的,BS 在内部使用 Unicode。
对于BS3
:
美丽的汤给你Unicode,该死的
当您的文档被解析时,它已被转换为 Unicode。Beautiful Soup 在其数据结构中仅存储 Unicode 字符串。
对于BS4
,当发生这种情况时,文档解释得更清楚一点:
您可以传入一个字符串或一个打开的文件句柄……首先,将文档转换为 Unicode,然后将 HTML 实体转换为 Unicode 字符……`
换句话说,它立即解码数据。所以,如果你得到 mojibake,你必须在它进入 BS 之前修复它,而不是之后。
构造函数的输入BeautifulSoup
可以采用 8 位字节字符串或文件,并尝试找出编码。有关详细信息,请参阅编码。您可以通过打印来检查它是否猜对了soup.original_encoding
。如果它没有猜测ISO-8859-1
或同义词,您唯一的选择是使其明确:decode
在传递它之前的字符串,使用 Unicode 模式打开文件encoding
,等等。
来自任何 BS 对象的结果,以及作为参数传递给任何方法的任何内容,都将始终是 UTF-8(如果它们是字节字符串)。所以,调用decode('iso-8859-1')
你从 BS 中得到的东西肯定会破坏一些东西,如果它还没有被破坏的话。
而且您无论如何都不想这样做。正如您在评论中所说,“我正在输出到 SQLite3 数据库。” 好吧,sqlite3 总是使用 UTF-8。(你可以pragma
在运行时用 a 改变它,或者在编译时改变默认值,但这基本上破坏了 Python 接口,所以……不要。)Python 接口只允许在 Py2 中使用 UTF-8 str
(当然在 Py2 unicode
/Py3 str
,没有编码。)因此,如果您尝试将 BS 数据编码为 Latin-1 以存储在数据库中,则会产生问题。只需按原样存储 Unicode,或者如果必须将其编码为 UTF-8(仅限 Py2)。
如果您不想弄清楚所有这些,只需在初始调用后在任何地方使用 Unicode BeautifulSoup
,您就永远不会出错。