引言
Beautiful Soup
是 Python 最流行的 HTML/XML 解析库,能够从复杂的网页文档中高效提取数据。以下是其核心知识点及示例代码。
一、库简介
1. 核心模块
- BeautifulSoup:主类,用于构建文档树结构
- Tag:表示 HTML/XML 标签的对象
- NavigableString:标签内文本内容的特殊字符串类型
- Comment:处理 HTML 注释的特殊类型
2. 主要特性
- 自动修复不规范文档
- 支持多种解析器(html.parser, lxml, html5lib)
- 提供 DOM 树遍历和搜索方法
二、安装与基础使用
1. 安装
bash
pip install beautifulsoup4 # 安装 bs4
pip install lxml # 推荐安装高效解析器
2. 基础示例
python
from bs4 import BeautifulSoup
# 示例 HTML 文档
html_doc = """
<html>
<head><title>测试页面</title></head>
<body>
<div class="content">
<h1 id="main-title">网页标题</h1>
<p class="text">第一段文字</p>
<p class="text special">特殊段落</p>
<a href="https://example.com">示例链接</a>
</div>
</body>
</html>
"""
# 创建 BeautifulSoup 对象(指定解析器)
soup = BeautifulSoup(html_doc, 'lxml')
# 获取标题文本
title = soup.title.string
print("页面标题:", title) # 输出: 测试页面
三、核心操作示例
1. 标签查找
python
# 查找第一个 div 标签
div_tag = soup.find('div')
print("Div 类名:", div_tag['class']) # 输出: ['content']
# 查找所有 p 标签
p_tags = soup.find_all('p')
for i, p in enumerate(p_tags, 1):
print(f"段落{i}:", p.text)
2. CSS 选择器
python
# 选择类名为 "text" 的所有元素
text_elements = soup.select('.text')
print("找到的文本元素数量:", len(text_elements)) # 输出: 2
# 选择 id 为 main-title 的元素
title = soup.select_one('#main-title')
print("主标题:", title.text) # 输出: 网页标题
3. 属性操作
python
# 获取链接的 href 属性
link = soup.find('a')
print("链接地址:", link['href']) # 输出: https://example.com
# 修改标签属性
link['target'] = '_blank'
print("修改后的链接标签:", link)
4. 文档树导航
python
# 父子节点操作
body_tag = soup.body
print("Body 的直接子节点数量:", len(list(body_tag.children))) # 输出: 3(含空白文本节点)
# 兄弟节点查找
first_p = soup.find('p')
next_p = first_p.find_next_sibling('p')
print("下一个段落的类名:", next_p['class']) # 输出: ['text', 'special']
5. 文本处理
python
# 获取所有文本内容(合并结果)
full_text = soup.get_text()
print("完整文本:", full_text.strip())
# 处理注释
comment_html = "<p>这是一段<!-- 这是注释 -->测试文本</p>"
comment_soup = BeautifulSoup(comment_html, 'lxml')
comment = comment_soup.p.next_element.next_element
print("注释内容:", comment) # 输出: 这是注释
四、高级应用示例
1. 提取表格数据
python
table_html = """
<table>
<tr><th>姓名</th><th>年龄</th></tr>
<tr><td>张三</td><td>25</td></tr>
<tr><td>李四</td><td>30</td></tr>
</table>
"""
table_soup = BeautifulSoup(table_html, 'lxml')
rows = table_soup.find_all('tr')
# 提取表格数据到字典列表
data = []
for row in rows[1:]: # 跳过表头
cols = row.find_all('td')
data.append({
'name': cols[0].text,
'age': int(cols[1].text)
})
print("表格数据:", data)
2. 处理嵌套结构
python
# 多层嵌套选择
nested_html = """
<div class="article">
<div class="header">
<h2>文章标题</h2>
<div class="meta">2023-08-01</div>
</div>
<div class="content">
<p>正文内容...</p>
</div>
</div>
"""
nested_soup = BeautifulSoup(nested_html, 'lxml')
meta = nested_soup.select('.article > .header > .meta')
print("发布日期:", meta[0].text) # 输出: 2023-08-01
五、注意事项
-
解析器选择:
html.parser
:Python 内置,速度一般lxml
:速度快,需要额外安装html5lib
:容错性最好,速度最慢
-
编码处理:
python# 显式指定编码 soup = BeautifulSoup(html_content, 'lxml', from_encoding='utf-8')
-
动态内容处理:
- 对于 JavaScript 渲染的页面,需要配合 Selenium 或 Requests-HTML 使用