XPath 语法完全指南:从入门到精通
.## 一、XPath 简介XPathXML Path Language是一种在 XML 文档中查找信息的语言它使用路径表达式来选取 XML 文档中的节点或节点集。XPath 最初是为 XSLT 和 XPointer 设计的核心组件但如今已被广泛应用于Web 爬虫Python 的 lxml、Scrapy 框架自动化测试Selenium、Appium 元素定位数据提取从 HTML/XML 中解析结构化数据配置文件XML 配置的动态查询XPath 1.0 是最广泛支持的版本本文所有语法均基于 XPath 1.0。二、XPath 基本概念2.1 节点类型XPath 将 XML 文档抽象为七种节点类型节点类型说明示例元素节点ElementXML 标签book属性节点Attribute标签属性id1文本节点Text标签内文本Hello World注释节点CommentXML 注释!-- comment --处理指令节点PI?xml ...?命名空间节点Namespacexmlns:xsl根节点Root文档根不可见/2.2 节点关系父节点Parent每个元素和属性都有且仅有一个父节点子节点Children元素节点可以有零个或多个子元素兄弟节点Siblings拥有相同父节点的节点祖先节点Ancestor父节点、祖父节点等后代节点Descendant子节点、孙子节点等三、XPath 路径表达式3.1 基本语法XPath 使用类似文件系统的路径表达式来定位节点/ # 从根节点开始绝对路径 // # 从当前节点的后代中选取相对路径 . # 当前节点 .. # 当前节点的父节点 # 选取属性 * # 通配符匹配任意元素节点 * # 通配符匹配任意属性节点 node() # 匹配任意类型节点 text() # 匹配文本节点 comment() # 匹配注释节点3.2 常用路径示例假设有如下 XML 文档bookstorebookcategorycookingtitlelangenEveryday Italian/titleauthorGiada De Laurentiis/authoryear2005/yearprice30.00/price/bookbookcategorychildrentitlelangenHarry Potter/titleauthorJ K. Rowling/authoryear2005/yearprice29.99/price/book/bookstore表达式结果bookstore选取 bookstore 元素的所有子节点/bookstore选取根元素 bookstorebookstore/book选取 bookstore 下所有 book 子元素//book选取所有 book 元素无论位置bookstore//book选取 bookstore 后代中所有 book//lang选取所有名为 lang 的属性/bookstore/book[1]第一个 book 子元素/bookstore/book[last()]最后一个 book 子元素/bookstore/book[position()3]前两个 book//title[lang]所有带 lang 属性的 title//title[langen]lang 属性为 en 的 title/bookstore/book[price30]price 大于 30 的 book四、XPath 轴Axes轴定义了相对于当前节点的节点集是 XPath 强大定位能力的核心。4.1 轴的语法轴名称::节点测试[谓词]4.2 常用轴一览轴名称缩写说明ancestor当前节点的所有祖先父、祖父…ancestor-or-self祖先及自身attribute当前节点的所有属性child默认当前节点的所有子元素descendant//当前节点的所有后代descendant-or-self后代及自身following文档中当前节点结束标签之后的所有节点following-sibling当前节点之后的所有兄弟节点namespace当前节点的所有命名空间节点parent..当前节点的父节点preceding文档中当前节点开始标签之前的所有节点preceding-sibling当前节点之前的所有兄弟节点self.当前节点自身4.3 轴使用示例# 选取当前节点的所有子元素 child::book # 选取当前节点的所有属性 attribute::lang # 等价于 lang # 选取当前节点所有后代中的 title descendant::title # 等价于 .//title # 选取当前节点的父节点 parent::node() # 等价于 .. # 选取当前节点之后的所有兄弟 book following-sibling::book # 选取当前节点之前的所有兄弟 preceding-sibling::*五、XPath 谓词Predicates谓词用于过滤节点集写在方括号[]中返回布尔值。5.1 数值谓词# 第一个子元素 /bookstore/book[1] # 最后一个子元素 /bookstore/book[last()] # 倒数第二个 /bookstore/book[last()-1] # 前三个 /bookstore/book[position() 3]5.2 属性谓词# 存在 lang 属性 //title[lang] # lang 属性等于 en //title[langen] # 多属性条件 //input[typetext and nameusername] # 属性包含某值 //div[contains(class, header)] # 属性以某值开头 //a[starts-with(href, https)]5.3 文本谓词# 文本完全匹配 //a[text()登录] # 文本包含 //button[contains(text(), 提交)] # normalize-space 去除空白后匹配 //div[normalize-space(text())Hello World]5.4 逻辑运算符# and //book[categorycooking and price25] # or //book[price10 or price50] # not() //div[not(class)] # ! //title[lang!en]六、XPath 内置函数XPath 1.0 提供了丰富的内置函数分为四大类。6.1 节点集函数函数说明last()当前节点集中最后一个节点的位置position()当前节点在节点集中的位置从1开始count(node-set)返回节点集中的节点数量name(node-set?)返回节点的名称local-name(node-set?)返回不带命名空间前缀的名称namespace-uri(node-set?)返回命名空间 URI6.2 字符串函数函数说明string(obj?)将对象转换为字符串concat(string, string, ...)字符串拼接contains(s1, s2)s1 是否包含 s2starts-with(s1, s2)s1 是否以 s2 开头substring(s, start, len?)截取子串substring-before(s1, s2)s2 之前的部分substring-after(s1, s2)s2 之后的部分string-length(s?)字符串长度normalize-space(s?)去除首尾空白合并中间空白translate(s1, s2, s3)字符替换6.3 数值函数函数说明number(obj?)转换为数字sum(node-set)节点集数值求和floor(num)向下取整ceiling(num)向上取整round(num)四舍五入6.4 布尔函数函数说明boolean(obj)转换为布尔值not(condition)逻辑非true()返回 truefalse()返回 falselang(string)判断节点语言七、XPath 运算符7.1 完整运算符列表运算符说明示例|节点集合并//h1 | //h2加法price 10-减法price - 5*乘法price * 1.1div除法price div 2mod取模position() mod 2等于id1!不等于class!hidden小于price10小于等于price10大于price10大于等于price10and逻辑与a and bor逻辑或a or b注意XPath 中除法用div取模用mod不能用/和%。八、实战场景HTML 元素定位8.1 Selenium 常用定位技巧fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBy driverwebdriver.Chrome()# 1. 通过 id 定位driver.find_element(By.XPATH,//*[idusername])# 2. 通过 class 定位注意 class 是多值属性driver.find_element(By.XPATH,//div[contains(class, login-form)])# 3. 通过文本定位driver.find_element(By.XPATH,//button[text()登录])# 4. 通过父子关系定位driver.find_element(By.XPATH,//form[idlogin]//input[typesubmit])# 5. 通过兄弟节点定位driver.find_element(By.XPATH,//label[text()密码]/following-sibling::input)# 6. 通过索引定位从1开始driver.find_element(By.XPATH,(//table//tr)[2]/td[3])8.2 Python lxml 解析示例fromlxmlimportetree html html body ul classmenu lia href9/home首页/a/li lia href/about关于/a/li lia href/contact联系/a/li /ul /body /html treeetree.HTML(html)# 获取所有链接文本textstree.xpath(//ul[classmenu]//a/text())print(texts)# [首页, 关于, 联系]# 获取所有 href 属性hrefstree.xpath(//ul[classmenu]//a/href)print(hrefs)# [/home, /about, /contact]# 同时获取文本和属性itemstree.xpath(//ul[classmenu]//a)foriteminitems:print(item.text,item.get(href))九、高级技巧与注意事项9.1 XPath 轴的组合使用# 找到当前 td 所在行的第一个 td ./ancestor::tr/td[1] # 找到当前元素前面最近的一个 h2 ./preceding::h2[1] # 找到当前 div 的下一个兄弟 section ./following-sibling::section[1]9.2 常见陷阱索引从 1 开始XPath 的位置索引从 1 开始不是 0class 属性是多值的classbtn只能匹配完全等于 btn 的元素推荐用contains(class, btn)text() 只取直接子文本如果元素内有嵌套标签text()只取直接文本节点用.或string()获取全部文本命名空间问题有命名空间的文档需要注册命名空间才能正确查询谓词中的 and/orXPath 用and/or不是/||9.3 性能优化建议优先使用//会扫描整个文档尽量缩小范围如//div[idmain]//a避免使用//*全文档扫描属性定位比文本定位更稳定复杂页面优先使用 id 或唯一 class 作为锚点十、总结XPath 是一门强大而简洁的查询语言掌握它的核心在于理解节点模型把 XML/HTML 看作节点树熟练路径表达式/、//、.、..、是基础善用轴定位轴是 XPath 区别于 CSS 选择器的核心优势灵活运用谓词谓词让定位更精确掌握常用函数contains、text()、position()等是高频使用无论是爬虫、自动化测试还是数据解析XPath 都是不可或缺的工具。希望本文能帮助你系统掌握 XPath 语法。如果本文对你有帮助欢迎点赞、收藏、关注三连支持

相关新闻

国产模型做代码审查:误报率测试脚本让我重新认识了 OpenAI

国产模型做代码审查:误报率测试脚本让我重新认识了 OpenAI

国产模型做代码审查:误报率测试脚本让我重新认识了 OpenAI 代码审查工具选型实战:国产大模型与OpenAI的工程化差距 当灰度上线前的最后一天,CI流水线突然被数百条SonarQube误报淹没时,整个技术团队陷入了混乱。作为技术负责人,我意识到这次尝试用国产大模型替代OpenAI进行代码…

2026/10/20 7:16:25 阅读更多 →
数组、链表还是哈希表:先对齐输入规模再比较

数组、链表还是哈希表:先对齐输入规模再比较

数组、链表还是哈希表:先对齐输入规模再比较 渐近复杂度只描述增长趋势,数组、链表和哈希表的实际差异还受内存布局、访问分布与并发方式影响。先固定输入规模和操作比例,再比较时间、分配与正确性。 先检查比较是否公平 基准测试需要固定实现…

2026/10/18 20:16:12 阅读更多 →
Atcoder Beginner Contest 151-180

Atcoder Beginner Contest 151-180

Atcoder Beginner Contest 151 Atcoder Beginner Contest 151-CSDN博客 AtCoder Beginner Contest 152 AtCoder Beginner Contest 152_atcoder beginner contest 152 b-CSDN博客 AtCoder Beginner Contest 153 AtCoder Beginner Contest 153_atcoder beginner contest153e-CSDN…

2026/10/19 1:24:04 阅读更多 →

最新新闻

E5080A网分实战:从S参数校准到滤波器与天线测试

E5080A网分实战:从S参数校准到滤波器与天线测试

射频工程师的工位上,网络分析仪永远是C位。做天线的人离不开它,调滤波器的人离不开它,测放大器、测混频器、测射频线缆的人统统离不开它。E5080A就是这一类设备里我这两年用得最多的一台。它对得起“主力”这两个字,四平八稳&…

2026/10/20 7:16:57 阅读更多 →
SDIO接口接Wi-Fi:从原理到Linux驱动移植的实战指南

SDIO接口接Wi-Fi:从原理到Linux驱动移植的实战指南

做了好几年的嵌入式开发,SDIO接口和Wi-Fi的组合我前前后后碰了十来个项目,从工业数据采集器到智能家居网关,方案里都离不开一颗主控加一颗SDIO Wi-Fi模块。身边刚入行的同事经常问我:Wi-Fi为什么要走SDIO?它和SPI、USB…

2026/10/20 7:16:57 阅读更多 →
FlinkCDC对接达梦数据库实时同步全链路实践

FlinkCDC对接达梦数据库实时同步全链路实践

简介:本资源是一套面向大数据开发工程师与实时数仓建设者的FlinkCDC达梦数据库日志级实时同步实践方案,聚焦国产数据库场景下的低延迟、高可靠数据捕获需求,适用于政务、金融等对数据安全与自主可控要求较高的业务系统构建。压缩包共5个文件&…

2026/10/20 7:16:57 阅读更多 →
vfork与fork:嵌入式Linux进程创建的安全陷阱与正确用法

vfork与fork:嵌入式Linux进程创建的安全陷阱与正确用法

1. 一段段错误代码引出的vfork真相事情要从一次凌晨的联调说起。当时我负责某产线设备的录像模块,主控芯片是某家的工业级处理器,跑着定制版Linux系统。业务逻辑不复杂:主进程收到抓拍指令后,派生一个子进程去执行图像抓取&#x…

2026/10/20 7:16:57 阅读更多 →
CDFA模块助力YOLO26:对比驱动特征融合实现小目标检测涨点

CDFA模块助力YOLO26:对比驱动特征融合实现小目标检测涨点

做目标检测的这些年,我最大的感受是:小目标检测是最难涨点,也最值得涨点的方向。远距离行人、密集车流、航拍小物件、工业缺陷,这些场景全靠小目标撑着,而通用模型在它们面前经常“睁眼瞎”。最近我在YOLO26上做了一轮…

2026/10/20 7:16:57 阅读更多 →
蓝牙AOA定位网关上报数据格式全解析:从字段含义到兼容排查

蓝牙AOA定位网关上报数据格式全解析:从字段含义到兼容排查

做蓝牙AOA定位的项目,拿到网关以后大家第一件事往往不是调算法,而是先搞清楚一个问题:网关上报的数据到底长什么样。很多项目在“跑通Demo”和“精准定位”之间反复横跳,根子就出在把上报数据格式理解错了,或者压根没理…

2026/10/20 7:15:57 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →