XPath 中的“节点(Node)”完全讲解
(看完这篇你就彻底明白 XPath 的 7 种节点到底是什么,怎么用)
XPath 把整个 HTML/XML 文档看成一棵节点树,一切操作都是在这棵树上找节点、跳来跳去。
1. XPath 到底有 7 种节点类型(记住这 7 个就够用了)
| 节点类型 | 中文名 | 说明与常见用法 | 举例(HTML片段) |
|---|---|---|---|
| 1. 元素节点(Element) | 元素 | 最常见,就是标签 、、 等 | //div、//a[@href] |
| 2. 属性节点(Attribute) | 属性 | id、class、href、src 等 | //input[@id=’kw’] → @id 就是属性节点 |
| 3. 文本节点(Text) | 文本 | 标签里面的纯文字 | //a/text() → 取出“新闻”两个字 |
| 4. 命名空间节点 | 命名空间 | XML 中才常见,HTML 基本不用 | 忽略 |
| 5. 处理指令节点 | 处理指令 | 这种,HTML 不用 | 忽略 |
| 6. 注释节点(Comment) | 注释 | //comment() | |
| 7. 根节点(Root) | 文档根节点 | 整个文档最顶层,位于 之上,只有一个 | / (单个斜杠就代表根节点) |
日常 99% 的场景你只关心前 3 种:元素、属性、文本。
2. 实际例子(百度首页一段代码)
<div id="s-top-left">
<a href="https://www.baidu.com/news" class="mnav">新闻</a>
<!-- 哈哈我是注释 -->
<a href="https://haokan.baidu.com">哈哈</a>
</div>
这时候的节点树长这样:
根节点(/)
└── 元素节点 <html>
└── 元素节点 <div id="s-top-left">
├── 属性节点 id="s-top-left"
├── 文本节点(换行+空格)
├── 元素节点 <a href="...">
│ ├── 属性节点 href="https://www.baidu.com/news"
│ ├── 属性节点 class="mnav"
│ └── 文本节点 "新闻"
├── 文本节点(换行+空格)
├── 注释节点 <!-- 哈哈我是注释 -->
├── 文本节点(换行+空格)
└── 元素节点 <a ...>哈哈</a>
3. 常用节点写法一览表(直接背)
| 想要取什么 | XPath 写法 | 结果 |
|---|---|---|
| 所有 div 元素节点 | //div | 所有 标签 |
| id 属性节点的值 | //div/@id | “s-top-left” |
| 第一个 a 的文本节点 | (//a)[1]/text() | “新闻” |
| 所有文本节点(包括空格) | //div/text() | 三个文本节点(换行、空格) |
| 干净的文本(推荐) | normalize-space(//div) | “新闻 哈哈”(自动去掉多余空格换行) |
| 所有注释 | //comment() | |
| 整个文档根节点 | / | 整个文档 |
| 当前节点 | . | 正在操作的那个节点 |
| 父节点 | .. 或 parent::* | 上级标签 |
4. 超级实用的文本节点技巧(爬虫必备)
//a[text()='新闻'] → 完全相等(前后不能有空格)
//a[contains(text(),'新闻')] → 包含“新闻”即可(但只看第一个文本节点)
//a[contains(.,'新闻')] → 推荐!点 . 代表当前元素所有文本节点拼接后的内容
normalize-space(//div) → 把所有子文本+空格合并后去首尾空格
string(//div) → 把整个元素下所有文本连起来取第一条(常用于取价格)
5. 一句话总结节点关系
- 元素节点 → 可以有子元素、属性、文本
- 属性节点 → 永远是元素的“孩子”,但不是元素节点
- 文本节点 → 永远是元素节点的“孩子”
- 根节点 → 整棵树的最高祖宗,/ 代表它
记住:在 XPath 眼里,网页不是标签堆出来的,而是由这 7 种节点搭成的一棵家谱树。
现在你已经彻底搞懂 XPath 的“节点”了!
要不要我给你出一套节点练习题?10分钟搞定就能写出任何复杂定位~