导读:本期聚焦于小伙伴创作的《如何用XPath通过兄弟节点和子节点关系精准定位网页元素?》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《如何用XPath通过兄弟节点和子节点关系精准定位网页元素?》有用,将其分享出去将是对创作者最好的鼓励。

XPath高级定位:利用兄弟节点和子节点关系查找目标元素

在做网页数据抓取或者自动化测试时,我们经常会遇到元素没有唯一id、class属性,或者属性值动态变化的情况,这时候基础的XPath定位方式往往不够用。这时候就可以利用XPath的轴定位能力,通过兄弟节点、子节点的关系来精准找到目标元素,解决很多复杂场景下的定位问题。

一、基本概念铺垫

在了解兄弟和子节点定位前,先明确两个基础概念:

  • 子节点:某个元素内部直接嵌套的元素,就是该元素的子节点,子节点的子节点属于后代节点,不属于直接子节点。
  • 兄弟节点:和当前元素拥有同一个父节点的元素,都互为兄弟节点,分为前面的哥哥节点和后面的弟弟节点。

XPath提供了专门的轴(axis)语法来描述节点之间的关系,常用的和兄弟、子节点相关的轴有:child(子节点)、following-sibling(后面的兄弟节点)、preceding-sibling(前面的兄弟节点)。

二、子节点定位实战

子节点定位是最常用的场景,比如我们要找某个<div>标签下第二个<p>标签,或者找某个列表下所有<li>子元素,都可以用子节点相关语法。

基础的子节点定位可以直接用/分隔,比如找<div id="content">下的所有<p>子节点,语法是//div[@id='content']/p,如果是找后代节点(不管嵌套多少层)就用//,比如//div[@id='content']//p

如果需要更精准的控制,比如找第N个子节点,可以结合索引使用,注意XPath的索引是从1开始的,不是从0开始。下面是一个具体的示例,假设我们有如下HTML结构:

<div class="article">
  <h3>文章标题</h3>
  <p class="intro">文章简介内容</p>
  <p class="content">文章正文第一段</p>
  <p class="content">文章正文第二段</p>
  <div class="footer">
    <span>发布时间:2024-05-01</span>
    <span>作者:张三</span>
  </div>
</div>

如果我们想定位到class为article的div下的第二个<p class="content">元素,就可以用下面的XPath表达式:

//div[@class='article']/p[@class='content'][2]

这里的/p[@class='content'][2]就是找当前div下的第二个class为content的p子节点,如果要找所有content类的p子节点,去掉索引即可:

//div[@class='article']/p[@class='content']

三、兄弟节点定位实战

兄弟节点定位在元素属性没有明显特征,但相邻元素有特征的时候非常好用,比如表单里<label>标签后面跟着的<input>输入框,或者表格里某个单元格后面的操作按钮,都可以通过兄弟节点关系定位。

1. 后面的兄弟节点(following-sibling)

following-sibling轴用来找当前节点之后的所有同级兄弟节点,语法是当前节点/following-sibling::目标节点类型[条件]

还是用上面的HTML结构举例,如果我们要找到<h3>标题后面的第一个<p>标签,也就是简介的那个p,就可以用:

//h3[text()='文章标题']/following-sibling::p[1]

如果要找标题后面所有的p标签,就可以去掉索引:

//h3[text()='文章标题']/following-sibling::p

再举个表单的场景,假设HTML结构如下:

<form id="login-form">
  <label for="username">用户名:</label>
  <input type="text" id="username" name="username">
  <label for="password">密码:</label>
  <input type="password" id="password" name="password">
  <button type="submit">登录</button>
</form>

如果我们要通过label的文本找到对应的input输入框,就可以用following-sibling:

//label[text()='用户名:']/following-sibling::input[1]
//label[text()='密码:']/following-sibling::input[1]

2. 前面的兄弟节点(preceding-sibling)

preceding-sibling轴和following-sibling相反,用来找当前节点之前的所有同级兄弟节点,语法是当前节点/preceding-sibling::目标节点类型[条件]

还是用上面的登录表单举例,如果我们要通过input输入框找到对应的label标签,就可以用:

//input[@id='username']/preceding-sibling::label[1]
//input[@id='password']/preceding-sibling::label[1]

这里的[1]表示找当前input前面最近的一个label兄弟节点,因为preceding-sibling返回的顺序是从近到远,所以第一个就是紧挨着的前面的label。

四、组合使用场景

实际场景中我们经常需要把子节点和兄弟节点的定位组合起来用,比如要找某个列表下,第二个<li>元素后面的所有<span>标签,就可以先定位到li,再用following-sibling找后面的span。

假设有如下列表结构:

<ul class="user-list">
  <li>
    <span class="name">张三</span>
    <span class="age">20</span>
  </li>
  <li>
    <span class="name">李四</span>
    <span class="age">22</span>
  </li>
  <li>
    <span class="name">王五</span>
    <span class="age">25</span>
  </li>
</ul>

如果我们要找到第二个li(李四那一行)下的age的span,可以先定位到第二个li,再找子节点span:

//ul[@class='user-list']/li[2]/span[@class='age']

如果我们要找到李四的li后面,王五的li下的name的span,就可以组合兄弟和子节点:

//li[span[@class='name' and text()='李四']]/following-sibling::li[1]/span[@class='name']

这个表达式的逻辑是:先找到包含name为李四的span的li,然后找它后面的第一个li兄弟节点,再找这个li下的class为name的span子节点,就精准定位到了王五的名字span。

五、注意事项

  • XPath的索引从1开始,和很多编程语言的数组从0开始不同,写索引的时候不要搞错。
  • 使用兄弟节点轴的时候,要注意返回节点的顺序,following-sibling是从当前节点往后按顺序返回,preceding-sibling是从当前节点往前按从近到远的顺序返回。
  • 如果页面结构可能变化,尽量不要用太固定的索引,比如[3]这种,优先用属性条件来过滤,比如[@class='xxx'],这样定位更稳定。
  • 写好的XPath可以在浏览器的开发者工具里验证,在Elements面板按Ctrl+F,输入XPath表达式,能匹配到元素就说明语法正确。

XPath定位兄弟节点following_sibling子节点网页抓取

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。