XPath 最佳实践
核心原则
- •使用唯一特征 - 优先用 id、class、data-* 属性
- •避免过于具体 - 不要写死完整路径
- •使用属性匹配 - 比位置索引更稳定
- •考虑页面变化 - 结构变化时仍能工作
基础语法
节点选择
code
//* # 所有节点 //li # 所有 li 节点 //li/a # li 的直接子节点 a //li//a # li 的所有子孙节点 a //a/.. # a 的父节点
文本和属性
code
//a/text() # 获取文本 //a/@href # 获取属性值 //a[@href='link.html'] # 属性匹配
推荐写法 vs 不推荐写法
列表项选择
code
# 推荐 - 使用 class 属性 //li[@class="item"] //li[contains(@class, "item")] # 不推荐 - 使用完整路径 /html/body/div/ul/li
下一页按钮
code
# 推荐 - 使用文本或位置 //a[contains(text(), "下一页")] //ul[@class="pagination"]/li[last()-1]/a # 不推荐 - 硬编码索引 //ul/li[7]/a
高级技巧
多属性匹配
code
//li[contains(@class, "item") and @data-type="link"] //li[@class="item" or @class="active"]
属性多值匹配
code
# class="li li-first" 的情况 //li[contains(@class, "li-first")]
位置选择
code
//li[1] # 第一个 //li[last()] # 最后一个 //li[position()<=3] # 前三个 //li[position()>1] # 除第一个外
兄弟节点
code
//li[@class="current"]/following-sibling::li[1] # 下一个兄弟 //li[@class="current"]/preceding-sibling::li[1] # 上一个兄弟
常见场景
列表页标题
code
//ul[@class="list"]//a/text() //div[contains(@class, "item")]//h3/text()
列表页链接
code
//ul[@class="list"]//a/@href //div[contains(@class, "item")]//a/@href
分页-下一页
code
//a[contains(text(), "下一页")] //a[contains(text(), "下页")] //li[last()-1]/a //a[@class="next"]
分页-无下一页按钮
code
//a[@class="current"]/following-sibling::a[1]
常用方法
| 方法 | 说明 | 示例 |
|---|---|---|
| contains() | 包含匹配 | //li[contains(@class, "item")] |
| text() | 获取文本 | //a/text() |
| last() | 最后位置 | //li[last()] |
| position() | 当前位置 | //li[position()<3] |
| normalize-space() | 去空白 | normalize-space(text()) |