文章目录
- 前言
- [一、 安装](#一、 安装)
-
- [1.1 BeautifulSoup 安装](#1.1 BeautifulSoup 安装)
- [1.2 第三方解析器安装](#1.2 第三方解析器安装)
- [1.3 主要解析器对比](#1.3 主要解析器对比)
- 二、快速上手
-
- [2.1 使用字符串解析](#2.1 使用字符串解析)
- [2.2 解析本地文件](#2.2 解析本地文件)
- [2.3 对象类型](#2.3 对象类型)
- [2.4 文档树搜索](#2.4 文档树搜索)
- [2.5 CSS 选择器](#2.5 CSS 选择器)
前言
BeautifulSoup 是一个用于从 HTML 或 XML 文件中提取数据的 Python 库。它能够将文档转换为可遍历的树形结构,并提供导航、查找和修改功能。该库会自动将输入文档转换为 Unicode 编码,输出时则转换为 UTF-8 编码。
BeautifulSoup 支持 Python 标准库中的 HTML 解析器以及多种第三方解析器。默认情况下使用 Python 内置的 HTML 解析器,但其解析效率相对较低。如果处理的数据量较大或解析频率较高,建议使用性能更强的 lxml 解析器。
一、 安装
1.1 BeautifulSoup 安装
Debian/Ubuntu 系统(通过包管理器安装):
bash
bash
apt-get install python-bs4
通用安装方式(使用 pip):
bash
bash
pip install beautifulsoup4
1.2 第三方解析器安装
如需使用 lxml 或 html5lib 解析器,可按以下方式安装:
系统包管理器安装:
bash
bash
apt-get install python-lxml python-html5lib
pip 安装:
bash
bash
pip install lxml html5lib
1.3 主要解析器对比
| 解析器 | 使用方法 | 优势 | 劣势 |
|---|---|---|---|
| Python 标准库 | BeautifulSoup(markup, "html.parser") | Python 内置;执行速度适中;文档容错能力强 | Python 2.7.3 / 3.2.2 前版本容错能力较差 |
| lxml HTML 解析器 | BeautifulSoup(markup, "lxml") | 速度快;文档容错能力强 | 需要安装 C 语言库 |
| lxml XML 解析器 | BeautifulSoup(markup, ["lxml-xml"]) 或 BeautifulSoup(markup, "xml") | 速度快;唯一支持 XML 的解析器 | 需要安装 C 语言库 |
| html5lib | BeautifulSoup(markup, "html5lib") | 最佳容错性;以浏览器方式解析;生成 HTML5 格式文档 | 速度慢;不依赖外部扩展 |
二、快速上手
将文档传入 BeautifulSoup 构造函数即可获得文档对象,支持传入字符串或文件句柄。
2.1 使用字符串解析
示例 HTML 字符串:
python
python
html = '''
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>BeautifulSoup学习</title>
</head>
<body>
Hello BeautifulSoup
</body>
</html>
'''
解析示例:
python
python
from bs4 import BeautifulSoup
# 使用默认解析器
soup = BeautifulSoup(html, 'html.parser')
# 使用 lxml 解析器
soup = BeautifulSoup(html, 'lxml')
2.2 解析本地文件
假设上述 HTML 内容保存于 index.html 文件:
python
python
# 使用默认解析器
soup = BeautifulSoup(open('index.html'), 'html.parser')
# 使用 lxml 解析器
soup = BeautifulSoup(open('index.html'), 'lxml')
2.3 对象类型
BeautifulSoup 将文档转换为树形结构,节点可分为四种类型:Tag、NavigableString、BeautifulSoup、Comment。
1)Tag 对象
Tag 对象对应 HTML/XML 中的原始标签:
python
python
soup = BeautifulSoup('<title>BeautifulSoup学习</title>', 'lxml')
tag = soup.title
print(tag) # <title>BeautifulSoup学习</title>
print(type(tag)) # <class 'bs4.element.Tag'>
常用属性:
name 属性:获取或修改标签名
python
python
print(tag.name) # title
tag.name = 'title1' # 修改标签名
print(tag) # <title1>BeautifulSoup学习</title1>
属性操作:支持类字典方式访问
python
python
soup = BeautifulSoup('<title class="tl">BeautifulSoup学习</title>', 'lxml')
tag = soup.title
# 获取属性
print(tag['class']) # ['tl']
print(tag.attrs) # {'class': ['tl']}
# 增删改属性
tag['id'] = 1 # 添加属性
tag['class'] = 'tl1' # 修改属性
del tag['class'] # 删除属性
2)NavigableString 对象
包装标签中的文本内容:
python
python
text = tag.string
print(text) # BeautifulSoup学习
# 替换文本内容
tag.string.replace_with('New Content')
3)BeautifulSoup 对象
表示整个文档对象,具有特殊属性:
python
python
soup = BeautifulSoup('<title class="tl">BeautifulSoup学习</title>', 'lxml')
print(soup.name) # [document]
4)Comment 对象
特殊类型的 NavigableString,表示注释内容:
python
python
soup = BeautifulSoup('<title class="tl"><!--Hello BeautifulSoup--></title>', 'html.parser')
comment = soup.title.string
print(comment) # Hello BeautifulSoup(注释符号自动去除)
2.4 文档树搜索
1)find_all() 方法
完整签名:find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
参数示例:
python
python
# 按标签名查找
print(soup.find_all('title')) # [<title class="tl">Hello BeautifulSoup</title>]
# 按属性查找
soup.find_all(attrs={"class": "tl"})
# 限制搜索深度
soup.find_all('title', recursive=False)
# 按文本内容查找
import re
soup.find_all(text='BeautifulSoup') # 字符串
soup.find_all(text=re.compile('BeautifulSoup')) # 正则表达式
soup.find_all(text=['head', 'title']) # 列表
soup.find_all(text=True) # 所有文本节点
# 限制结果数量
soup.find_all('a', limit=1)
# 多条件过滤
soup.find_all(href=re.compile("elsie"), id='link1')
# 特殊属性搜索(如 data-* 属性)
soup.find_all(attrs={'data-foo': 'value'})
2)find() 方法
返回第一个匹配的节点(无匹配时返回 None):
python
python
soup = BeautifulSoup('<a id="link1">Elsie</a><a id="link2">Elsie</a>', 'html.parser')
print(soup.find_all('a', limit=1)) # 返回列表
print(soup.find('a')) # 返回单个节点
3)其他搜索方法
| 方法 | 功能描述 |
|---|---|
| find_parents() / find_parent() | 搜索父辈节点 |
| find_next_siblings() / find_next_sibling() | 搜索后续兄弟节点 |
| find_previous_siblings() / find_previous_sibling() | 搜索前序兄弟节点 |
| find_all_next() / find_next() | 搜索后续所有节点 |
| find_all_previous() / find_previous() | 搜索前序所有节点 |
2.5 CSS 选择器
BeautifulSoup 支持 CSS 选择器语法,通过 .select() 或 .select_one() 方法调用:
python
python
soup = BeautifulSoup('<body><a id="link1" class="elsie">Elsie</a></body>', 'html.parser')
# 基本选择器
soup.select('a') # 所有 <a> 标签
soup.select('.elsie') # 按类名选择
soup.select('#link1') # 按 ID 选择
soup.select('a[class]') # 有 class 属性的 <a> 标签
soup.select('a[class="elsie"]') # 属性精确匹配
soup.select_one('.elsie') # 返回第一个匹配
# 层级选择器
soup.select('body a') # 后代选择器
soup.select('body > a') # 直接子元素
soup.select('#link1 ~ .elsie') # 后续所有兄弟元素
soup.select('#link1 + .elsie') # 相邻兄弟元素
# 多条件选择
soup.select('#link1, #link2') # 多个选择器