文章目录
- 前言
- 一、 安装
- 1.1 BeautifulSoup 安装
- 1.2 第三方解析器安装
- 1.3 主要解析器对比
- 二、快速上手
- 2.1 使用字符串解析
- 2.2 解析本地文件
- 2.3 对象类型
- 2.4 文档树搜索
- 2.5 CSS 选择器
前言
BeautifulSoup 是一个用于从 HTML 或 XML 文件中提取数据的 Python 库。它能够将文档转换为可遍历的树形结构,并提供导航、查找和修改功能。该库会自动将输入文档转换为 Unicode 编码,输出时则转换为 UTF-8 编码。
BeautifulSoup 支持 Python 标准库中的 HTML 解析器以及多种第三方解析器。默认情况下使用 Python 内置的 HTML 解析器,但其解析效率相对较低。如果处理的数据量较大或解析频率较高,建议使用性能更强的 lxml 解析器。
一、 安装
1.1 BeautifulSoup 安装
Debian/Ubuntu 系统(通过包管理器安装):
bashapt-getinstallpython-bs4通用安装方式(使用 pip):
bashpipinstallbeautifulsoup41.2 第三方解析器安装
如需使用 lxml 或 html5lib 解析器,可按以下方式安装:
系统包管理器安装:
bashapt-getinstallpython-lxml python-html5libpip 安装:
bashpipinstalllxml html5lib1.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 html=''' <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>BeautifulSoup学习</title> </head> <body> Hello BeautifulSoup </body> </html> '''解析示例:
pythonfrombs4importBeautifulSoup# 使用默认解析器soup=BeautifulSoup(html,'html.parser')# 使用 lxml 解析器soup=BeautifulSoup(html,'lxml')2.2 解析本地文件
假设上述 HTML 内容保存于 index.html 文件:
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 soup=BeautifulSoup('<title>BeautifulSoup学习</title>','lxml')tag=soup.titleprint(tag)# <title>BeautifulSoup学习</title>print(type(tag))# <class 'bs4.element.Tag'>常用属性:
name 属性:获取或修改标签名
pythonprint(tag.name)# titletag.name='title1'# 修改标签名print(tag)# <title1>BeautifulSoup学习</title1>属性操作:支持类字典方式访问
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'# 修改属性deltag['class']# 删除属性2)NavigableString 对象
包装标签中的文本内容:
python text=tag.stringprint(text)# BeautifulSoup学习# 替换文本内容tag.string.replace_with('New Content')3)BeautifulSoup 对象
表示整个文档对象,具有特殊属性:
python soup=BeautifulSoup('<title class="tl">BeautifulSoup学习</title>','lxml')print(soup.name)# [document]4)Comment 对象
特殊类型的 NavigableString,表示注释内容:
python soup=BeautifulSoup('<title class="tl"><!--Hello BeautifulSoup--></title>','html.parser')comment=soup.title.stringprint(comment)# Hello BeautifulSoup(注释符号自动去除)2.4 文档树搜索
1)find_all() 方法
完整签名:find_all(name=None, attrs={}, recursive=True, text=None, limit=None, **kwargs)
参数示例:
python# 按标签名查找print(soup.find_all('title'))# [<title class="tl">Hello BeautifulSoup</title>]# 按属性查找soup.find_all(attrs={"class":"tl"})# 限制搜索深度soup.find_all('title',recursive=False)# 按文本内容查找importre 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')# 特殊属性搜索(如>.find_all(attrs={'data-foo':'value'})2)find() 方法
返回第一个匹配的节点(无匹配时返回 None):
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 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')# 多个选择器