HTML文档树被解析成一个BeautifulSoup类的对象。这个类的构造函数需要一个必需的参数,即HTML字符串或指向HTML文件的文件对象。构造函数还有其他可选参数,其中重要的是features
参数。
BeautifulSoup(markup, features)
在这里,markup
是一个HTML字符串或文件对象。features
参数指定了要使用的解析器,可能是特定的解析器如"lxml"、"lxml-xml"、"html.parser"或"html5lib";或者是要使用的标记类型("html"、"html5"、"xml")。
如果没有给出features
参数,BeautifulSoup会选择安装的最佳HTML解析器。BeautifulSoup认为lxml的解析器是最好的,其次是html5lib的,再次是Python内置的解析器。
您可以指定以下选项之一:
-
要解析的标记类型。目前BeautifulSoup支持的有"html"、"xml"和"html5"。
-
要使用的解析器库的名称。目前支持的选项有"lxml"、"html5lib"和"html.parser"(Python内置的HTML解析器)。
要安装lxml或html5lib解析器,请使用命令:
pip3 install lxml
pip3 install html5lib
这些解析器各有优缺点,如下所示:
解析器 |
使用示例 |
优点 |
缺点 |
Python's html.parser |
BeautifulSoup(markup, "html.parser") |
包含在标准库中 |
不如lxml快,不如html5lib宽容 |
lxml的HTML解析器 |
BeautifulSoup(markup, "lxml") |
非常快,宽容 |
外部C依赖 |
lxml的XML解析器 |
BeautifulSoup(markup, "lxml-xml") 或 BeautifulSoup(markup, "xml") |
非常快,目前唯一支持的XML解析器 |
外部C依赖 |
html5lib |
BeautifulSoup(markup, "html5lib") |
非常宽容,与浏览器解析页面相同,创建有效的HTML5 |
非常慢,外部Python依赖 |
不同的解析器会根据同一个文档创建不同的解析树。HTML解析器和XML解析器之间的差别最大。这里是一个简短的文档,作为HTML解析:
示例
from bs4 import BeautifulSoup
soup = BeautifulSoup("<a><b /></a>", "html.parser")
print(soup)
输出
<a><b></b></a>
一个空的<b />
标签不是有效的HTML。因此,解析器把它转换成一个<b></b>
标签对。
同样的文档现在作为XML解析。注意空的<b />
标签保持不变,并且文档被赋予了一个XML声明而不是放入一个<html>
标签中。
示例
from bs4 import BeautifulSoup
soup = BeautifulSoup("<a><b /></a>", "xml")
print(soup)
输出
<?xml version="1.0" encoding="utf-8"?>
<a><b/></a>
对于一个完全形成的HTML文档,所有的HTML解析器都会产生相似的解析树,尽管一个解析器可能会比另一个更快。
但是,如果HTML文档不完美,不同类型的解析器会产生不同的结果。看看当"<a></p>"
用不同的解析器解析时,结果是如何不同的:
lxml解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup("<a></p>", "lxml")
print(soup)
输出
<html><body><a></a></body></html>
注意,多余的</p>
标签被简单地忽略了。
html5lib解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup("<a></p>", "html5lib")
print(soup)
输出
<html><head></head><body><a><p></p></a></body></html>
html5lib解析器为其配对了一个打开的<p>
标签。这个解析器还在文档中添加了一个空的<head>
标签。
内置html解析器
from bs4 import BeautifulSoup
soup = BeautifulSoup("<a></p>", "html.parser")
print(soup)
输出
<a></a>
这个解析器也忽略了关闭的</p>
标签。但是这个解析器并没有尝试通过添加<body>
标签来创建一个格式良好的HTML文档,甚至没有添加<html>
标签。
html5lib解析器使用的技术是HTML5标准的一部分,因此它最有资格被称为“正确”的方式。