XPath 实例(超详细)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观
在网页数据抓取、自动化测试或文档解析等场景中,XPath 是一种不可或缺的工具。它通过类似路径的表达式,帮助开发者精准定位 HTML 或 XML 文档中的目标节点。然而,对于编程初学者而言,XPath 的语法和逻辑可能显得抽象复杂。本文将通过 “XPath 实例” 的详细讲解,结合实际案例和代码演示,逐步解析其核心概念与应用技巧,帮助读者从基础到进阶掌握这一技能。
什么是 XPath?
XPath(XML Path Language)是一种用于在 XML 或 HTML 文档中定位节点的语言。它通过路径表达式描述节点的层级关系,类似于文件系统中的目录路径。例如,/html/body/div
就是一个简单的 XPath 表达式,表示从根节点 html
开始,依次查找其子节点 body
和 div
。
XPath 的核心作用
- 定位节点:如提取网页中的标题、价格或链接。
- 筛选条件:根据属性值或文本内容过滤节点。
- 数据提取:结合编程语言(如 Python 或 JavaScript),提取目标数据。
XPath 基础语法:路径与节点类型
1. 路径表达式的基本结构
XPath 的路径分为两种:绝对路径和相对路径。
- 绝对路径:从根节点
/
开始,逐层指定节点路径,例如/html/body/div/p
。 - 相对路径:以当前上下文节点为起点,例如
//div[@class='content']
(从任意位置查找class
为content
的div
)。
示例:HTML 结构与 XPath 路径
假设以下 HTML 片段:
<html>
<body>
<div class="container">
<h1>欢迎来到示例页面</h1>
<p>这是第一个段落。</p>
<div class="content">
<a href="/link">点击此处</a>
</div>
</div>
</body>
</html>
- 绝对路径:
/html/body/div[@class='container']/h1
可定位到标题<h1>
。 - 相对路径:
//div[@class='content']/a
可直接定位到<a>
标签,无需从根节点开始。
2. 节点类型与通配符
XPath 支持多种节点类型和通配符:
| 符号 | 含义 | 示例 |
|------|--------------------------|--------------------------|
| /
| 根节点或直接子节点 | /html/body
|
| //
| 任意层级子节点 | //div
(查找所有 div
)|
| .
| 当前节点 | .//p
(当前节点下所有 p
)|
| *
| 任意节点类型 | //div/*
(div
下所有子节点)|
| @
| 属性节点 | //img/@src
(获取 src
属性)|
定位技巧:轴(Axis)、谓词与条件筛选
1. 轴(Axis):定义节点搜索方向
轴决定了 XPath 表达式在文档中的搜索范围。常用轴包括:
| 轴 | 含义 | 示例 |
|-------------|--------------------------|--------------------------|
| child
| 当前节点的子节点 | child::div
|
| parent
| 父节点 | parent::body
|
| ancestor
| 所有祖先节点 | ancestor::div
|
| descendant
| 当前节点的后代节点 | descendant::p
|
| following
| 当前节点之后的所有节点 | following::div
|
示例:使用 ancestor
轴
//div[@id='target']/ancestor::div
该表达式会找到 id
为 target
的 div
的所有祖先 div
节点。
2. 谓词(Predicate):添加筛选条件
谓词通过 [...]
语法添加条件,例如:
//div[@class='active']
:查找class
属性为active
的div
。//a[2]
:选取第二个<a>
标签。//p[contains(text(), '示例')]
:包含特定文本的段落。
实例:动态筛选商品价格
假设网页中商品价格存储在类名为 price
的 <span>
标签中:
<div class="product">
<h2>商品名称</h2>
<span class="price">¥ 99.00</span>
</div>
XPath 表达式://span[@class='price']/text()
可直接提取文本内容 ¥ 99.00
。
进阶用法:函数、命名空间与条件表达式
1. 常用函数
XPath 提供多种函数辅助数据处理:
text()
:获取节点文本内容。contains()
:判断属性或文本是否包含子字符串。starts-with()
:判断是否以特定字符串开头。position()
:获取节点在当前集合中的位置索引。
示例:提取以 http
开头的链接
//a[starts-with(@href, 'http')]/@href
该表达式会筛选出所有 href
属性以 http
开头的链接。
2. 处理命名空间
当 XML 文档包含命名空间时,需通过 local-name()
或 namespace-uri()
处理。例如:
//*[local-name()='Book' and contains(@category, 'Technology')]
此表达式忽略命名空间,直接定位标签名为 Book
且类别含 Technology
的节点。
实际案例:电商商品信息抓取
场景描述
假设需从某电商页面提取商品标题、价格和链接,其 HTML 结构如下:
<div class="product-list">
<div class="product-item">
<h3 class="title">智能手表 Pro X</h3>
<span class="price">¥ 1,299</span>
<a href="/products/123" class="detail-link">查看详情</a>
</div>
<div class="product-item">
<h3 class="title">无线耳机 Mini</h3>
<span class="price">¥ 399</span>
<a href="/products/456" class="detail-link">查看详情</a>
</div>
</div>
步骤解析
- 定位商品容器:
//div[@class='product-list']
- 遍历每个商品项:
//div[@class='product-item']
- 提取标题:
//div[@class='product-item']/h3/text()
- 提取价格:
//div[@class='product-item']/span[@class='price']/text()
- 提取链接:
//div[@class='product-item']/a/@href
Python 实现示例
使用 lxml
库解析 HTML 并提取数据:
from lxml import html
tree = html.fromstring(html_content)
products = tree.xpath("//div[@class='product-item']")
for product in products:
title = product.xpath(".//h3[@class='title']/text()")[0]
price = product.xpath(".//span[@class='price']/text()")[0]
link = product.xpath(".//a/@href")[0]
print(f"标题:{title} | 价格:{price} | 链接:{link}")
常见问题与优化建议
问题 1:XPath 表达式返回空值
可能原因:
- 节点路径错误(如拼写错误或层级不符)。
- 动态加载内容未完全加载(需等待或使用 JavaScript 渲染工具)。
问题 2:如何提高 XPath 的稳定性?
- 避免绝对路径:优先使用
//
和属性筛选,而非层级路径。 - 减少依赖类名:若类名易变,可结合文本内容或相邻节点定位。
- 使用模糊匹配:
contains()
或starts-with()
替代精确匹配。
结论
通过本文的 “XPath 实例” 分析,读者应能掌握从基础语法到实际应用的完整流程。XPath 的核心在于理解节点关系与路径逻辑,而熟练运用则需通过不断实践和调试。无论是自动化测试、数据抓取还是文档解析,XPath 都是开发者工具箱中不可或缺的利器。建议读者结合具体项目需求,尝试编写更多实例,逐步提升对复杂场景的应对能力。
提示:本文案例代码可在本地环境复现,修改 HTML 结构或表达式即可验证不同效果。