Beautiful Soup – 编码

Beautiful Soup – 编码

所有的HTML或XML文档都是以一些特定的编码写成的,如ASCII或UTF-8。然而,当你将该HTML/XML文档加载到BeautifulSoup时,它已经被转换为Unicode。

>>> markup = "<p>I will display £</p>"
>>> Bsoup = BeautifulSoup(markup)
>>> Bsoup.p
<p>I will display £</p>
>>> Bsoup.p.string
'I will display £'

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

然而,并不是所有的时候,Unicode, Dammit都能猜对。由于要逐个字节地搜索文档以猜测其编码,这需要大量的时间。如果你已经知道编码,把它作为from_encoding传给BeautifulSoup构造函数,你可以节省一些时间并避免错误。

下面是一个例子,BeautifulSoup把一个ISO-8859-8的文件错误地识别为ISO-8859-7的文件。

>>> markup = b"<h1>\xed\xe5\xec\xf9</h1>"
>>> soup = BeautifulSoup(markup)
>>> soup.h1
<h1>νεμω</h1>
>>> soup.original_encoding
'ISO-8859-7'
>>>

为了解决上述问题,使用from_encoding – 将其传递给BeautifulSoup。

>>> soup = BeautifulSoup(markup, from_encoding="iso-8859-8")
>>> soup.h1
<h1>ולש </h1>
>>> soup.original_encoding
'iso-8859-8'
>>>

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

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

输出编码

BeautifulSoup的输出是UTF-8文件,与输入BeautifulSoup的文件无关。下面是一个文档,其中的抛光字符是以ISO-8859-2格式存在的。

html_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>
"""


>>> soup = BeautifulSoup(html_markup)
>>> 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'

在上面的例子中,我们对整个文档进行了编码,然而你可以对汤中的任何特定元素进行编码,就像它们是一个python字符串一样。

>>> soup.p.encode("latin-1")
b'<p>0My first paragraph.</p>'
>>> soup.h1.encode("latin-1")
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 “对上述内容进行编码,就会产生”☃”,表明没有这种表示法。

>>> print (tag.encode("latin-1"))
b'<b>☃</b>'
>>> print (tag.encode("ascii"))
b'<b>☃</b>'

Unicode, Dammit

Unicode, Dammit主要用于当输入的文件是未知的格式(主要是外语),而我们想用一些已知的格式(Unicode)进行编码,同时我们也不需要Beautifulsoup来做这些事情。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程