XPath 高级用法与常见问题
一、基础概念回顾
- XPath 是用于在 XML/HTML 文档中定位元素的语言。
- 基本语法:
/表示从根节点开始查找。//表示从任意位置查找。@attr表示选择属性。[条件]用于筛选节点。text()提取节点文本。
二、常见问题及注意点
1. 使用位置定位
//*[@id="ratings-and-reviews"]/div[15]
-
[15]表示取第 15 个 div。 -
可以用
position()函数替代:div[position()=15 or position()=16]优点:可以同时选择多个位置的元素,更灵活。
重点:位置是基于同级节点顺序的,如果结构变化可能导致索引错误。
2. 属性筛选
错误写法:
//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]/a aria-label="Previous"
正确写法:
//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]/a[@aria-label="Previous"]
重点:
- XPath 属性必须用
[@属性名="值"]。 - 可以与位置、文本条件联合使用。
3. 文本筛选
如果要选出文本为 $0 的节点:
//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]/a[text()="$0"]
/text()提取直接文本节点。- 如果要在条件里判断,可用
text()="$0"或string()方法。
4. 布尔判断与节点存在性
- 检查节点是否存在:
count(//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]/a) > 0
- 检查
li[1]存在但a不存在:
count(//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]) > 0
and count(//*[@id="ratings-and-reviews"]/div[15]/div/div[1]/nav/ul/li[1]/a) = 0
重点:
- XPath 本身不能直接返回布尔值,需要用
count()判断。 - 可在 Python 中根据返回列表长度判断。
5. 使用 | 合并节点
错误示例:
//*[@id="ratings-and-reviews"]/div[position()=15 or position()=16]/div/div[1]/nav/ul/li[last()]/button|a[@aria-label="Next"]
- 这里
|优先级低,导致a[@aria-label="Next"]被当作全局选择,而不是受前面 div 限制。
正确示例:
//*[@id="ratings-and-reviews"]/div[position()=15 or position()=16]/div/div[1]/nav/ul/li[last()]/*[self::button or self::a[@aria-label="Next"]]
重点:
- 合并多个节点时,
|的优先级可能导致逻辑错误。 - 用括号或
self::明确作用范围。
三、实用技巧总结
- 文本筛选:用
text()或string(),注意空格。 - 位置筛选:
position()可以选择多个索引。 - 属性筛选:用
[@attr="value"],可以与文本/位置联合。 - 布尔判断:
count()+ 条件,适合判断节点存在性。 - 多节点合并:用
self::或加括号避免|优先级问题。 - 调试技巧:
- 可以先用
//a或//*[@id="ratings-and-reviews"]//a看有哪些节点,再精确定位。 - 用 Python 的
lxml或浏览器控制台测试 XPath 表达式。
- 可以先用
评论