Beautiful Soup - 编码



所有 HTML 或 XML 文档都以某种特定的编码编写,例如 ASCII 或 UTF-8。但是,当您将该 HTML/XML 文档加载到 BeautifulSoup 中时,它已转换为 Unicode。

示例

from bs4 import BeautifulSoup
markup = "<p>I will display £</p>"
soup = BeautifulSoup(markup, "html.parser")
print (soup.p)
print (soup.p.string)

输出

<p>I will display £</p>
I will display £

上述行为是因为 BeautifulSoup 内部使用名为 Unicode,Dammit 的子库来检测文档的编码,然后将其转换为 Unicode。

但是,并非所有时候,Unicode,Dammit 都能正确猜测。由于文档逐字节搜索以猜测编码,因此需要大量时间。如果您已经知道编码,可以通过将其作为 from_encoding 传递给 BeautifulSoup 构造函数,从而节省一些时间并避免错误。

下面是一个示例,其中 BeautifulSoup 将 ISO-8859-8 文档错误识别为 ISO-8859-7 −

示例

from bs4 import BeautifulSoup
markup = b"<h1>\xed\xe5\xec\xf9</h1>"
soup = BeautifulSoup(markup, 'html.parser')
print (soup.h1)

print (soup.original_encoding)

输出

<h1>翴檛</h1>
ISO-8859-7

要解决上述问题,请使用 from_encoding 将其传递给 BeautifulSoup −

示例

from bs4 import BeautifulSoup
markup = b"<h1>\xed\xe5\xec\xf9</h1>"
soup = BeautifulSoup(markup, "html.parser", from_encoding="iso-8859-8")
print (soup.h1)

print (soup.original_encoding)

输出

<h1>םולש</h1>
iso-8859-8

从 BeautifulSoup 4.4.0 开始添加的另一个新功能是 exclude_encoding。当您不知道正确的编码,但确定 Unicode,Dammit 显示的结果错误时,可以使用它。

soup = BeautifulSoup(markup, exclude_encodings=["ISO-8859-7"])

输出编码

无论输入到 BeautifulSoup 的文档是什么,BeautifulSoup 的输出都是 UTF-8 文档。下面是一个文档,其中波兰语字符以 ISO-8859-2 格式存在。

示例

markup = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
   <HEAD>
      <META HTTP-EQUIV="content-type" CONTENT="text/html; charset=iso-8859-2">
   </HEAD>
   <BODY>
   ą ć ę ł ń ó ś ź ż Ą Ć Ę Ł Ń Ó Ś Ź Ż
   </BODY>
</HTML>
"""

from bs4 import BeautifulSoup

soup = BeautifulSoup(markup, "html.parser", from_encoding="iso-8859-8")
print (soup.prettify())

输出

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
   <head>
      <meta content="text/html; charset=utf-8" http-equiv="content-type"/>
   </head>
   <body>
      ą ć ę ł ń ó ś ź ż Ą Ć Ę Ł Ń Ó Ś Ź Ż
   </body>
</html>

在上面的示例中,如果您注意到,<meta> 标签已被重写以反映从 BeautifulSoup 生成的文档现在为 UTF-8 格式。

如果您不希望生成的输出为 UTF-8,可以在 prettify() 中分配所需的编码。

print(soup.prettify("latin-1"))

输出

b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">\n<html>\n <head>\n  <meta content="text/html; charset=latin-1" http-equiv="content-type"/>\n </head>\n <body>\n  ą ć ę ł ń \xf3 ś ź ż Ą Ć Ę Ł Ń \xd3 Ś Ź Ż\n </body>\n</html>\n'

在上面的示例中,我们对整个文档进行了编码,但是您可以对 soup 中的任何特定元素进行编码,就像它们是 python 字符串一样 −

soup.p.encode("latin-1")
soup.h1.encode("latin-1")

输出

b'<p>My first paragraph.</p>'
b'<h1>My First Heading</h1>'

任何在您选择的编码中无法表示的字符都将转换为数字 XML 实体引用。下面是一个这样的示例 −

markup = u"<b>\N{SNOWMAN}</b>"
snowman_soup = BeautifulSoup(markup)
tag = snowman_soup.b
print(tag.encode("utf-8"))

输出

b'<b>\xe2\x98\x83</b>'

如果您尝试以“latin-1”或“ascii”编码上述内容,它将生成“&#9731”,表示没有该字符的表示形式。

print (tag.encode("latin-1"))
print (tag.encode("ascii"))

输出

b'<b>☃</b>'
b'<b>☃</b>'

Unicode,Dammit

Unicode,Dammit 主要用于传入文档格式未知(主要是外语)并且我们希望以某种已知格式(Unicode)进行编码,并且我们不需要 Beautifulsoup 完成所有这些操作的情况。

广告

© . All rights reserved.