10.3 BeautifulSoup:HTMLXML 解析库


文章目录

  • 前言
  • [一、 安装](#一、 安装)
    • [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')        # 多个选择器

相关推荐
VCR__8 小时前
python第三次作业
开发语言·python
韩立学长8 小时前
【开题答辩实录分享】以《助农信息发布系统设计与实现》为例进行选题答辩实录分享
python·web
2401_838472519 小时前
使用Scikit-learn构建你的第一个机器学习模型
jvm·数据库·python
u0109272719 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
工程师老罗9 小时前
优化器、反向传播、损失函数之间是什么关系,Pytorch中如何使用和设置?
人工智能·pytorch·python
Fleshy数模9 小时前
我的第一只Python爬虫:从Requests库到爬取整站新书
开发语言·爬虫·python
CoLiuRs9 小时前
Image-to-3D — 让 2D 图片跃然立体*
python·3d·flask
小鸡吃米…9 小时前
机器学习 —— 训练与测试
人工智能·python·机器学习
七夜zippoe9 小时前
Docker容器化Python应用最佳实践:从镜像优化到安全防护
python·docker·云原生·eureka·容器化
喵手9 小时前
Python爬虫实战:采集“界面新闻-科技频道”的文章列表,提取标题、发布时间、摘要(导语)及原文链接(附 CSV 导出)!
爬虫·python·爬虫实战·python爬虫工程化实战·零基础python爬虫教学·采集新闻头条页数据·新闻数据采集