在使用 lxml 库解析网页数据时,每次都需要编写和测试  
 XPath  
 的路径表达式,显得非常  
 
 
 烦琐。为了解决这个问题, 
 Python  
 还提供了  
 Beautiful Soup  
 库提取  
 HTML  
 文档或  
 XML  
 文档的  
 
 
 节点。 
 Beautiful Soup  
 使用起来很便捷,受到了开发人员的推崇。接下来,本节先带领大家认  
 
 
 识  
 Beautiful Soup 
 ,再为大家介绍如何使用  
 Beautiful Soup  
 解析网页数据。 
 
一、Beautiful Soup 简介
 
         Beautiful Soup 是一个用于从  
 HTML  
 文档或  
 XML  
 文档中提取目标数据的  
 Python  
 库。它历  
 
 
 经了众多版本,其中  
 Beautiful Soup 3  
 已经停止开发与维护,官方推荐使用  
 Beautiful Soup 4 
 (简  
 
 
 称  
 bs4 
 )进行程序开发。截至本书完稿时, 
 Beautiful Soup  
 的最新版本是  
 4.4.0 
 。  
 
 
         为了快速解析 HTML  
 文档或  
 XML  
 文档的数据, 
 bs4  
 不仅提供了多种类型的解析器,还支  
 
 
 持  
 CSS  
 选择器。 
 bs4  
 通过解析器可以将  
 HTML  
 或  
 XML  
 文档、片段转换成节点树,节点树中  
 
 
 的每个节点对应一个  
 Python  
 类的对象。 
 bs4  
 库或  
 bs4.element  
 模块中提供了  
 Tag  
 类、  
 
 
 NavigableString  
 类、 
 BeautifulSoup  
 类、 
 Comment  
 类等  
 4  
 个比较重要的类。关于这  
 4  
 个类的具  
 
 
 体介绍如下。 
 
- bs4.element.Tag 类:表示 HTML 或 XML 中的元素,是最基本的信息组织单元。它有 两个非常重要的属性:表示元素名称的 name 和表示元素属性的 attrs。
 - bs4.element.NavigableString 类:表示 HTML 或 XML 元素中的文本(非属性字符串)。
 - bs4.BeautifulSoup 类:表示 HTML 或 XML 节点树中的全部内容,支持遍历节点树和 搜索节点树的大部分方法。
 - bs4.element.Comment类:表示元素内字符串的注释部分,是一种特殊的NavigableString 类的对象。
 
 
         bs4 的用法非常简单,一般分为如下  
 3  
 个步骤。  
 
 
 ( 
 1 
 )根据  
 HTML  
 或  
 XML  
 文档、片段创建  
 BeautifulSoup  
 类的对象。  
 
 
 ( 
 2 
 )通过  
 BeautifulSoup  
 类的对象的查找方法或  
 CSS  
 选择器定位节点。  
 
 
 ( 
 3 
 )通过访问节点的属性或节点的名称提取文本。  
 
二、创建 BeautifulSoup 类的对象
 
         要想使用 bs4  
 解析网页数据,需要先使用构造方法创建  
 BeautifulSoup  
 类的对象。  
 
 
 BeautifulSoup  
 类的构造方法的声明如下。 
 
BeautifulSoup(markup="", features=None, builder=None, 
 parse_only=None, from_encoding=None, exclude_encodings=None, 
 element_classes=None, **kwargs) 
 
         上述方法中常用参数的含义如下。  
 
- markup:必选参数,表示待解析的内容,可以取值为字符串或类似文件的对象。
 - features:可选参数,表示指定的解析器。该参数可以接收解析器名称或标记类型。其 中,解析器名称包括 lxml、lxml-xml、html.parser 和 html5lib,标记类型包括 html、html5 和 xml。
 - parse_only:可选参数,指定只解析部分文档。该参数需要接收一个 SoupStrainer 类的 对象。当文档太大而无法全部放入内存时,便可以考虑只解析一部分文档。
 - from_encoding:可选参数,指定待解析文档的编码格式。 值得一提的是,如果我们只需要解析 HTML 文档,那么在创建 BeautifulSoup 类的对象时 可以不用指定解析器。此时 Beautiful Soup 会根据当前系统安装的库自动选择解析器。解析器 的选择顺序为 lxml→html5lib→Python 标准库,但在以下两种情况下会发生变化。
 - 要解析的文档是什么类型?目前支持 html、xml 和 html5。
 - 指定使用哪种解析器?目前支持 lxml、html5lib 和 html.parser。
 
 
         如果指定的解析器没有安装,那么 Beautiful Soup  
 会自动选择其他方案。不过,目前只有  
 
 
 解析器  
 lxml  
 支持  
 XML  
 文档的解析。在当前系统中没有安装解析器  
 lxml  
 的情况下,即使创建  
 
 
 BeautifulSoup  
 对象时明确指定使用解析器  
 lxml 
 ,也无法得到解析后的内容。  
 
 
 下面通过一张表来区分上述  
 4  
 种解析器的优势与劣势,具体如表  
 4-7  
 所示。 
 
 
         接下来,通过一个例子来演示如何创建 BeautifulSoup 类的对象,具体代码如下。
1 from bs4 import BeautifulSoup 
2 html_doc = """<html><head><title>The Dormouse's story</title></head> 
3 <body> 
4 <p class="title"><b>The Dormouse's story</b></p> 
5 <p class="story">Once upon a time there were three little sisters; 
6 and their names were 
7 <a href="http://example.com/elsie" class="sister" id="link1">Elsie</a>, 
8 <a href="http://example.com/lacie" class="sister" id="link2">Lacie</a> and 
9 <a href="http://example.com/tillie" class="sister" id="link3">Tillie</a>; 
10 and they lived at the bottom of a well.</p> 
11 <p class="story">...</p> 
12 """ 
13 # 根据 html_doc 创建 BeautifulSoup 类的对象,并指定使用 lxml 解析器解析文档
14 soup = BeautifulSoup(html_doc, features='lxml') 
15 print(soup.prettify()) 
 
         在上述示例代码中,第 1  
 行代码导入了  
 BeautifulSoup  
 类,第  
 2 
 ~ 
 12  
 行定义了变量  
 html_doc  
 
 
 保存  
 HTML  
 代码片段,第  
 14  
 行代码根据  
 html_doc  
 创建了一个  
 BeautifulSoup  
 类的对象,并指  
 
 
 定使用解析器  
 lxml  
 来解析  
 HTML  
 文档,第  
 15  
 行代码输出了  
 soup.prettify() 
 执行的结果,其中  
 
 
 prettify() 
 方法会对  
 HTML  
 代码片段进行格式化处理,友好地显示  
 HTML  
 代码。  
 
 
 运行代码,输出如下结果。 
 
<html> 
 <head> 
 <title> 
 The Dormouse's story 
 </title> 
 </head> 
 <body> 
 <p class="title"> 
 <b> 
 The Dormouse's story 
 </b> 
 </p> 
 ……
 </body> 
</html> 
  


















