写爬虫或者处理 XML 配置文件时,经常需要"从一堆嵌套标签里精确定位某个节点",XPath(XML Path Language)就是为这个问题设计的路径查询语言,语法思路和文件系统路径有几分相似。
XPath(XML Path Language)是一套用来在 XML(或 HTML)文档结构里定位节点的路径表达式语言,1999 年由 W3C 制定为标准。它的核心思路是:把 XML/HTML 文档看作一棵树形结构(标签嵌套形成父子关系),用类似文件路径的语法,从根节点或任意节点出发,一步步描述"怎么走到目标节点"。爬虫工具(Scrapy、lxml)、浏览器自动化(Selenium)、以及编程语言内置的 document.evaluate API,都支持用 XPath 来精确抓取网页里的特定元素。
| 语法 | 含义 |
|---|---|
/ |
从根节点开始的绝对路径 |
// |
匹配文档任意位置的节点(不要求从根开始,最常用) |
nodeName |
选中该名字的所有子节点 |
* |
匹配任意名字的节点(通配符) |
@attr |
选中某个属性 |
. |
当前节点 |
.. |
父节点 |
比如 //div[@class="content"]//p 表示"文档任意位置下 class 属性为 content 的 div,再往下任意深度的所有 p 标签"——这是爬虫里最常见的写法模式:用 // 跳过不关心的中间层级,直接锚定关键的容器和目标标签。
方括号 [] 里写的是"谓语"(Predicate),给路径加上筛选条件:
//a[@href] 选中所有带 href 属性的 a 标签
//a[contains(@href, "detail")] 选中 href 属性包含 "detail" 的 a 标签
//li[3] 选中同级第 3 个 li 节点(注意:XPath 的索引从 1 开始,不是 0)
//div[last()] 选中最后一个 div
//input[@type="text" and @name="username"] 同时满足两个属性条件
索引从 1 开始是 XPath 和大多数编程语言(数组通常从 0 开始)的一个重要区别,也是新手最容易踩的坑之一。
XPath 内置了一些函数,能返回布尔值、字符串或数字,而不是节点集合:
text():选中节点的直接文本内容,比如 //h1/text() 取标题文字string(...):把节点内容转换成字符串,会拼接所有后代文本节点count(...):统计匹配到的节点数量boolean(...):转换成布尔值,常用于条件判断normalize-space(...):去除字符串首尾空白并把中间连续空白压缩成一个空格,处理网页里常见的排版空白很好用XPath 在严格的 XML 文档上表现最稳定;用在 HTML 上时,由于真实网站的 HTML 往往不完全规范(标签未闭合、嵌套错误),解析器通常需要用"宽松模式"做容错处理,写路径时也建议尽量用相对靠内层、有辨识度的属性(比如唯一的 class 或 id)作为锚点,而不是依赖容易变化的绝对层级路径,这样在页面结构小改动时脚本更不容易失效。
在线工具:xpath测试