新手必看:Python 爬虫解析 HTML 的 3 种方式(BeautifulSoup vs lxml vs XPath)
本文介绍了Python爬虫解析HTML的三种常用方法:BeautifulSoup、lxml和XPath。BeautifulSoup语法简单易用,适合新手;lxml基于C语言开发,解析速度快;XPath灵活强大,适合复杂网页。文章通过实例演示了每种方法的安装和使用,并对三者的性能、学习成本等进行了对比。建议新手先用BeautifulSoup入门,再逐步学习XPath,针对不同场景灵活选择。同时提供了
在 Python 爬虫流程中,“解析 HTML” 是承上启下的关键步骤 —— 它将爬虫获取的原始 HTML 字符串,转化为可提取数据的结构化对象。本文将聚焦新手最常用的 3 种解析方式:BeautifulSoup、lxml、XPath,通过 “安装 + 案例 + 对比” 的形式,帮你快速掌握核心技能。
一、前置准备:安装必备库
在开始前,需先安装 3 个核心库(requests用于获取 HTML,后三者用于解析),直接通过 pip 命令安装:
# 安装所有依赖库
pip install requests beautifulsoup4 lxml
- requests:发送 HTTP 请求,获取目标网页的 HTML 源码;
- beautifulsoup4:BeautifulSoup 的核心库,主打 “易用性”;
- lxml:lxml 和 XPath 的依赖库,主打 “解析速度”。
二、3 种解析方式实操教程
我们将以 “提取某测试网页的标题(<title>标签)、文章列表(<div class="article">下的<h3>标签)” 为例,分别演示 3 种方式的用法。
先获取测试 HTML(这里用本地模拟 HTML 简化流程,实际爬虫可替换为requests.get(url).text):
# 模拟目标网页的HTML源码
test_html = """
<html>
<head><title>测试页面</title></head>
<body>
<div class="article-list">
<div class="article">
<h3>第一篇文章</h3>
<p>文章简介1</p>
</div>
<div class="article">
<h3>第二篇文章</h3>
<p>文章简介2</p>
</div>
</div>
</body>
</html>
"""
1. BeautifulSoup:新手友好的 “傻瓜式” 解析
核心特点
- 语法简单,接近自然语言,无需记忆复杂规则;
- 自动修复不规范的 HTML(如缺失闭合标签);
- 依赖第三方解析器(推荐用 lxml,速度比默认的html.parser快)。
实操代码
from bs4 import BeautifulSoup
# 1. 创建BeautifulSoup对象(指定lxml解析器)
soup = BeautifulSoup(test_html, "lxml")
# 2. 提取数据
# 提取网页标题(<title>标签内容)
title = soup.title.text # 结果:"测试页面"
print("网页标题:", title)
# 提取所有文章标题(<div class="article">下的<h3>标签)
article_list = soup.find_all("div", class_="article") # 注意class_加下划线(避免与关键字冲突)
for article in article_list:
article_title = article.find("h3").text # 找到每个article下的h3标签
print("文章标题:", article_title) # 结果:"第一篇文章"、"第二篇文章"
关键方法
- soup.标签名:直接获取第一个匹配的标签(如soup.title);
- soup.find(标签名, 属性):获取第一个匹配的标签(如soup.find("div", class_="article"));
- soup.find_all(标签名, 属性):获取所有匹配的标签(返回列表);
- .text:提取标签内的文本内容;
- ["属性名"]:提取标签的属性(如soup.find("a")["href"]获取链接)。
2. lxml:高性能的 “C 语言级” 解析
核心特点
- 基于 C 语言开发,解析速度是 BeautifulSoup 的数倍;
- 支持 HTML 和 XML 解析,适合处理大体积网页;
- 语法比 BeautifulSoup 稍复杂,但比 XPath 简单。
实操代码
from lxml import etree
# 1. 将HTML字符串转为可解析的Element对象
html = etree.HTML(test_html) # 自动修复HTML语法错误
# 2. 提取数据
# 提取网页标题(直接定位<title>标签)
title = html.xpath("//title/text()")[0] # 这里暂用XPath语法,下文详解
print("网页标题:", title) # 结果:"测试页面"
# 提取所有文章标题(通过标签层级定位)
article_titles = html.xpath("//div[@class='article']/h3/text()")
for title in article_titles:
print("文章标题:", title) # 结果:"第一篇文章"、"第二篇文章"
关键说明
- lxml 的核心是etree.HTML()方法,它将 HTML 字符串转为 Element 对象;
- 提取数据主要依赖XPath 语法(下文单独讲解),也支持类似 BeautifulSoup 的 “标签遍历”(如html.find("div", class_="article")),但 XPath 是 lxml 的主流用法。
3. XPath:灵活强大的 “路径式” 解析
核心特点
- 一种专门用于定位 XML/HTML 元素的 “路径语言”,灵活性极高;
- 支持复杂的层级、属性、文本匹配,适合复杂网页;
- 需依赖 lxml 库(lxml 原生支持 XPath),学习成本略高于前两种。
先学 3 个核心 XPath 语法
|
语法 |
含义 |
示例 |
|
// |
从整个文档中查找(不局限层级) |
//div 查找所有 div 标签 |
|
@ |
匹配标签属性 |
//div[@class='article'] 查找 class 为 article 的 div |
|
text() |
提取标签内文本 |
//h3/text() 提取 h3 标签的文本 |
实操代码
from lxml import etree
# 1. 转为Element对象(与lxml步骤一致)
html = etree.HTML(test_html)
# 2. 用XPath提取数据
# 场景1:提取标题(精确匹配title标签)
title = html.xpath("//title/text()")[0] # XPath返回列表,取第一个元素
print("网页标题:", title)
# 场景2:提取带属性的标签(class="article"的div下的h3)
article_titles = html.xpath("//div[@class='article']/h3/text()")
print("所有文章标题:", article_titles) # 结果:["第一篇文章", "第二篇文章"]
# 场景3:提取标签属性(如假设文章有链接<a href="xxx">)
# 若HTML有<a href="https://test.com/1">第一篇文章</a>,则:
links = html.xpath("//div[@class='article']/a/@href")
print("文章链接:", links) # 结果:["https://test.com/1"]
三、3 种方式核心对比
|
维度 |
BeautifulSoup |
lxml |
XPath(基于 lxml) |
|
解析速度 |
慢(纯 Python 实现) |
快(C 语言实现) |
快(同 lxml) |
|
学习成本 |
低(语法直观) |
中(需了解 Element 对象) |
中高(需记忆 XPath 语法) |
|
灵活性 |
一般(复杂匹配较麻烦) |
较高 |
极高(支持复杂层级 / 属性匹配) |
|
容错性 |
高(自动修复不规范 HTML) |
较高 |
较高(同 lxml) |
|
适用场景 |
小项目、新手入门、HTML 不规范 |
中大型项目、追求效率 |
复杂网页(如嵌套深、属性多) |
四、新手选择建议
入门首选:BeautifulSoup
如果你刚接触爬虫,优先用 BeautifulSoup+lxml 解析器(既保留易用性,又提升速度),先掌握 “提取文本、属性” 等基础操作,建立信心。
进阶必学:XPath
当遇到 “嵌套层级深”(如div>ul>li>span)或 “多条件匹配”(如class为A且id为B的div)时,XPath 的优势会凸显,学会后能应对 90% 以上的解析场景。
效率优先:lxml
若你的爬虫需要处理大量数据(如爬取 thousands 级网页),直接用 lxml+XPath,避免因解析速度慢导致整体效率低下。
五、常见问题解决
解析乱码怎么办?
-
- BeautifulSoup:创建对象时指定编码,如soup = BeautifulSoup(html, "lxml", from_encoding="utf-8");
-
- lxml:先将 HTML 字符串转码,如html = etree.HTML(html_str.encode("utf-8").decode("utf-8"))。
找不到目标标签?
- lxml:先将 HTML 字符串转码,如html = etree.HTML(html_str.encode("utf-8").decode("utf-8"))。
-
- 检查标签属性是否正确(如 class 名是否有空格,XPath 中需完整匹配);
-
- 确认 HTML 是否为 “动态加载”(若数据由 JavaScript 生成,需用 Selenium/Pyppeteer 获取渲染后 HTML,本文 3 种方式只解析静态 HTML)。
总结
BeautifulSoup 是 “新手友好型工具”,lxml+XPath 是 “高效灵活型工具”。新手无需纠结 “必须学哪一个”,建议先掌握 BeautifulSoup 入门,再逐步过渡到 XPath—— 实际项目中,可根据网页复杂度和效率需求灵活切换,最终达到 “哪种方便用哪种” 的境界。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)