一、BeautifulSoup 的核心概念
-
定位:
-
用于解析 HTML/XML 文档的 Python 库,自动修复不规范的文档结构。
-
常与 Requests 配合使用(Requests 获取网页 → BeautifulSoup 解析内容)。
-
-
核心优势:
-
灵活的节点查找:支持多种查找方式(标签名、属性、CSS 选择器等)。
-
容错性强:自动处理不闭合标签、嵌套错误等。
-
树形结构操作:支持遍历、修改文档树。
-
二、安装与基础使用
1. 安装
pip install beautifulsoup4
2. 解析器选择(需额外安装)
-
lxml(推荐):速度快,容错强
pip install lxml
-
html.parser:Python 内置,无需安装
-
html5lib:容错性最强,但速度慢
pip install html5lib
3. 基础流程
from bs4 import BeautifulSoup
import requests
# 获取网页内容
response = requests.get("https://example.com")
html_content = response.text
# 创建 BeautifulSoup 对象
soup = BeautifulSoup(html_content, "lxml") # 指定解析器
# 提取数据
title = soup.title.text
print(title) # 输出网页标题
三、常用对象与方法
1. 四大对象类型
对象类型 | 描述 | 示例 |
---|---|---|
Tag | 标签节点(如 <div> , <a> ) | soup.div |
NavigableString | 标签内的文本(不含子标签) | tag.string |
BeautifulSoup | 整个文档对象 | soup |
Comment | 注释内容 | <!-- 注释 --> 的文本 |
2. 查找节点
-
find()
:返回第一个匹配的节点
first_link = soup.find("a") # 第一个 <a> 标签
find_all()
:返回所有匹配的节点列表
all_links = soup.find_all("a") # 所有 <a> 标签
- 按属性查找
# 查找 class 为 "header" 的 div
header = soup.find("div", class_="header")
# 查找 id 为 "main" 的标签
main = soup.find(id="main")
# 查找包含特定属性的标签
meta = soup.find("meta", {"name": "keywords"})
- CSS 选择器
# 选择所有 class 为 "item" 的 div
items = soup.select("div.item")
# 选择 id 为 "nav" 下的所有 a 标签
links = soup.select("#nav a")
3. 提取数据
-
标签文本
title = soup.title.text # 获取标签内文本(自动拼接子标签文本)
title = soup.title.get_text() # 同上
- 标签属性
link = soup.a
url = link["href"] # 获取属性(属性不存在时报错)
url = link.get("href", "") # 安全获取属性(不存在时返回默认值)
- 遍历节点
# 遍历直接子节点
for child in soup.ul.children:
print(child)
# 遍历所有后代节点
for descendant in soup.ul.descendants:
print(descendant)
四、高级功能
1. 处理兄弟节点与父节点
# 下一个兄弟节点
next_sibling = tag.next_sibling
# 上一个兄弟节点
previous_sibling = tag.previous_sibling
# 父节点
parent = tag.parent
2. 修改文档树
# 修改标签属性
tag["class"] = "new-class"
# 修改文本内容
tag.string = "新文本"
# 删除标签
tag.decompose()
3. 处理编码问题
# 指定输入/输出编码
soup = BeautifulSoup(html_content, "lxml", from_encoding="gbk")
output = soup.prettify(encoding="utf-8")
五、综合应用
from bs4 import BeautifulSoup
import requests
# 获取网页内容
url = "https://books.toscrape.com/"
response = requests.get(url)
soup = BeautifulSoup(response.text, "lxml")
# 提取所有书籍标题和价格
books = []
for book in soup.select("article.product_pod"):
title = book.h3.a["title"]
price = book.select_one("p.price_color").text
books.append({"title": title, "price": price})
# 输出结果
for book in books[:3]:
print(f"书名:{book['title']}, 价格:{book['price']}")
六、常见问题与解决
-
标签不存在时的处理
element = soup.find("div", class_="non-existent")
if element: # 先判断是否存在
print(element.text)
-
处理动态加载内容
-
BeautifulSoup 只能解析静态 HTML,动态内容需结合 Selenium 或直接调用接口。
-
-
性能优化
-
使用
lxml
解析器提升速度。 -
避免在循环中重复解析大文档。
-
七、最佳实践
-
始终指定解析器:推荐
lxml
(需安装)。 -
优先使用 CSS 选择器:语法简洁且功能强大。
-
处理编码问题:明确指定输入/输出编码,避免乱码。
-
异常处理:检查节点是否存在后再操作属性或文本。