Python + Selenium —— 网页元素定位之Xpath定位!

前面讲的定位方式,都能够很方便的定位到网页元素。但是这些属性并非所有的网页元素都具备,可以这么说,绝大部分情况下都很难保证元素具备这些属性。

也就是很多时候需要使用其他的方式来定位,在 WebDriver 中提供了 Xpath 和 Css 选择器两种语言来辅助定位。这两种语言都很强大,能够定位网页上的任意元素。

在网络爬虫中,也通常会用借助 lxml 库使用 Xpath 进行网页的解析。

目录

    • 基本定位语法

    • 元素属性定位

    • 层级属性结合定位

    • 使用谓语定位

    • 使用逻辑运算符

    • 使用文本定位

    • 使用部分匹配函数

    • 什么是 Xpath?

    • 绝对路径:

    • 相对路径

    • 验证 Xpath

什么是 Xpath?

Xpath 是一种用在 XML 文档中定位元素的语言,同样也支持 HTML 元素的解析。我们以百度中的HTML 代码为例。

<form id="form" name="f" action="/s" class="fm">
…<span class="bg s_ipt_wr quickdelete-wrap"><span class="soutu-btn"></span><input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off"></span><span class="bg s_btn_wr"><input type="submit" id="su" value="百度一下" class="bg s_btn"></span>
…
</form>

所谓 Xpath,是指 XML path language。path 就是路径,那么 Xpath 主要是通过路径来查找元素。

我们通过下面一张小图来了解一下 HTML 中的结构:

HTML 的结构就是树形结构,HTML 是根节点,所有的其他元素节点都是从根节点发出的。其他的元素都是这棵树上的节点Node,每个节点还可能有属性和文本。

节点之间存在各种关系:

  • 父节点(Parent):HTML 是 body 和 head 节点的父节点;

  • 子节点(Child):head 和 body 是 HTML 的子节点;

  • 兄弟节点(Sibling):拥有相同的父节点,head 和 body 就是兄弟节点。title 和 div 不是兄弟,因为他们不是同一个父节点。

  • 祖先节点(Ancestor):body 是 form 的祖先节点,爷爷辈及以上?;

  • 后代节点(Descendant):form 是 HTML 的后代节点,孙子辈及以下?。

Xpath 中的绝对路径从 HTML 根节点开始算,相对路径从任意节点开始。

通过开发者工具,我们可以拷贝到 Xpath 的绝对路径和相对路径代码:

但是由于拷贝出来的代码缺乏灵活性,也不全然准确。大部分情况下,都需要自己定义 Xpath 语句,因此 Xpath 语法还是有必要学习。

现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:691998057【暗号:csdn999】

绝对路径:

Xpath 中最直观的定位策略就是绝对路径。

以百度中的输入框和按钮为例,通过拷贝出来的 full Xpath:

/html/body/div[2]/div/div/div/div/form/span/input

这就是一个绝对路径我们可以看出,绝对路径是从根节点/html开始往下,一层层的表示出来直到需要的节点为止。

这明显不是理智的选项,因此了解以下即可,不用往心里去。

相对路径

除了绝对路径,Xpath 中更常用的方式是相对路径定位方法,以“//”开头。

相对路径可以从任意节点开始,一般我们会选取一个可以唯一定位到的元素开始写,可以增加查找的准确性。

相对路径可以通过以下的方式来定位元素:

基本定位语法

定位语法主要依赖于以下特殊符号:

表达式说明举例
/从根节点开始选取/html/div/span
//从任意节点开始选取//input
.选取当前节点
..选取当前节点的父节点//input/… 会选取 input 的父节点
@选取属性,或者根据属性选取//input[@data] 选取具备 data 属性的 input 元素
//@data 选取所有 data 属性
*通配符,表示任意节点或任意属性

元素属性定位

属性定位是通过 @ 符号指定需要使用的属性。

  1. 根据元素是否具备某个属性查找元素

//*[@data-recordid]

选取包含data-recordid属性的所有节点。可以定位到以下元素:

<tr role="row" data-boundview="gridview-1029" data-recordid="B36BCA33" ></tr>
  1. 根据属性是否等于某值查找元素

//span[@role='img']

选取属性 role 的属性值为 img 的所有节点。可以定位到以下元素:

<span role="img" class="x-btn-icon-el" unselectable="on" style=""></span>

注意,属性值必须要加引号,单双引号都可以。

层级属性结合定位

遇到某些元素无法精确定位的时候,可以查找其父级及其祖先节点,找到有确定的祖先节点后通过层级依次向下定位。

以下面的结构为例:

<form action="search" id="form" method="post"><span class="bg"><span class="soutu">搜索</span></span><span class="soutu"><input type="text" name="key" id="su"></span>
</form>
  1. 根据层级向下找,从 form 找到绿色的 span:

//form[@id="form"]/span/span
  1. 查找某元素内部的所有元素,选取 form 元素内部的所有 span:

//form[@id="form"]//span

第二个双斜杠,表示选取内部所有的 span,不管层级关系

  1. 使用星号找不特定的元素

//*[@id="form"]//*[@type="text"]

选取 id 属性为 form 的任意属性内部,并且 type 属性为 text 的任意元素。这里会找到 input。

  1. 使用..从下往上找,根据 input 查找其父节点 span:

//input[@name="key"]/..

注意最后的两个点,找到 input 节点的上级节点,如果还要再往上再加 /..

  1. 找同级节点:
    比如我们想通过第一个 span 标签去 找 div 标签。树形结构中,兄弟节点之间的关系是通过父节点建立起来的。所以可以先找到父节点,再通过父节点找同级节点。

//span[@class="bg"]/../div

先通过/..找到 span 的父节点,再通过父节点找到 div。

使用谓语定位

谓语是 Xpath 中用于描述元素位置。主要有数字下标、最后一个子元素last()、元素下标函数position()

  1. 使用下标的方式,从 form 找到 input :

//form[@id="form"]/span[2]/input

Xpath 中的下标从 1 开始。

  1. 查找最后一个子元素,选取 form 下的最后一个 span:

//form[@id="form"]/span[last()]
  1. 查找倒数第几个子元素,选取 form 下的倒数第一个 span:

//form[@id="form"]/span[last()-1]
  1. 使用 position() 函数,选取 from 下第二个 span:

//form[@id="form"]/span[position()=2]
  1. 使用 position() 函数,选取下标大于 2 的 span:

//form[@id="form"]/span[position()>2]

使用逻辑运算符

如果元素的某个属性无法精确定位到这个元素,我们还可以用逻辑运算符 and 连接多个属性进行定位,以百度输入框为例。

  1. 使用 and :

//*[@name='wd' and @class='s_ipt']

查找 name 属性为 wd 并且 class 属性为 s_ipt 的任意元素

  1. 使用 or

//*[@name='wd' or @class='s_ipt']

查找 name 属性为 wd 或者 class 属性为 s_ipt 的任意元素,取其中之一满足即可。

  1. 使用|,同时查找多个路径,取或:

//form[@id="form"]//span | //form[@id="form"]//input

选取 form 下所有的 span 和所有的 input。

使用文本定位

使用文本定位,是 Xpath 中的一大特色。在自动化测试中,为了让代码的可读性更高,可以使用文本的方式。
以下一个案例:


部分网页结构如下:

<tr><td valign="top"><input type="radio" name="payment" value="1" checked="" iscod="0"></td><td valign="top"><strong>支付宝</strong></td>
</tr>

其实我们需要点的是前的单选框,但是单选框没有任何特殊的标识,不够灵活。我们可以通过后面的名称,如(支付宝、余额支付等)来找到其对应行的 radio,再去点击。

我们就需要先通过文本定位到“支付宝”,再去找其同一行(tr)的 input 节点。如果理不清楚,我们可以先画一个结构图:

红色箭头表示查找路径,先定位到“支付宝”所在的 strong,再定位 td -> tr -> td - >input 。那么要定位“支付宝”文本,就需要用到 Xpath 中的函数 text() 或 string(),注意是函数,所以括号不能少。

text():当前元素节点包含的文本内容;
表达式//div[text()="文本"],能找到:

<div>文本</div>
  • 1

不能找到:

<div><span>文本</span></div>
  • 1

string():当前元素节点内部所有节点元素的文本内容。表达式//div[string()="文本"]上述两种情况都能找到。

好,接着写上面的内容。先通过 //strong[text()="支付宝"]定位到“支付宝”所在的元素 strong,再找上级 td -> tr,再向下找:

//strong[text()="支付宝"]/../../td[1]/input

也可以写为:

//td[string()="支付宝"]/../td[1]/input

使用部分匹配函数

Xpath 中有提供了几个函数,用来进行部分匹配。

函数说明举例
contains选取属性或者文本包含某些字符//div[contains(@id, ‘data’)] 选取 id 属性包含 data 的 div 元素
//div[contains(string(), ‘支付宝’)] 选取内部文本包含“支付宝”的 div 元素
starts-with选取属性或者文本以某些字符开头//div[starts-with(@id, ‘data’)] 选取 id 属性以 data 开头的 div 元素
//div[starts-with(string(), ‘银联’)] 选取内部文本以“银联”开头的 div 元素
ends-with选取属性或者文本以某些字符开头//div[ends-with(@id, ‘require’)] 选取 id 属性以 require 结尾的 div 元素
//div[ends-with(string(), ‘支付’)] 选取内部文本以“支付”结尾的 div 元素

验证 Xpath

验证 xpath 有两种方法:

  1. 在开发者工具的 Elements 中按Ctrl + F,在搜索框中输入 Xpath:

  1. 在开发者工具的 Console 中使用 $x()

下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

最后: 可以在公众号:自动化测试老司机! 免费领取一份216页软件测试工程师面试宝典文档资料。以及相对应的视频学习教程免费分享!,其中包括了有基础知识、Linux必备、Shell、互联网程序原理、Mysql数据库、抓包工具专题、接口测试工具、测试进阶-Python编程、Web自动化测试、APP自动化测试、接口自动化测试、测试高级持续集成、测试架构开发测试框架、性能测试、安全测试等。

如果我的博客对你有帮助、如果你喜欢我的博客内容,请 “点赞” “评论” “收藏” 一键三连哦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/646141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二叉树堆的应用实例分析:堆排序 | TOP-K问题

&#x1f4f7; 江池俊&#xff1a; 个人主页 &#x1f525;个人专栏&#xff1a; ✅数据结构冒险记 ✅C语言进阶之路 &#x1f305; 有航道的人&#xff0c;再渺小也不会迷途。 文章目录 前言一、堆排序1.1 排序思想1.2 堆排序过程&#xff08;图解&#xff09;1.3 堆排序代…

IP数据云:实战网络安全的得力利器

在当今数字化时代&#xff0c;企业和个人面临着日益复杂和频繁的网络安全威胁。为了应对这些挑战&#xff0c;IP数据云作为一项全面的网络安全解决方案&#xff0c;已经在多个实际案例中展现了其卓越的能力。 1、识别并隔离异常行为 挑战&#xff1a;一家大型金融机构发现其内…

Github 不能访问,提示:port 22: Connection timed out

问题描述 github clone 代码出现错误&#xff1a; $ git clone gitgithub.com:Atlan4/Fnirsi1013D.git Cloning into Fnirsi1013D... ssh: connect to host github.com port 22: Connection timed out fatal: Could not read from remote repository.Please make sure you ha…

Unity 外观模式(实例详解)

文章目录 示例1&#xff1a;初始化游戏场景中的多个子系统示例2&#xff1a;管理音频播放示例3&#xff1a;场景加载流程示例4&#xff1a;UI管理器示例5&#xff1a;网络服务通信 在Unity中使用外观模式&#xff08;Facade&#xff09;时&#xff0c;主要目的是为了简化复杂子…

Webpack5 基本使用 - 1

Webpack 是什么 webpack 的核心目的是打包&#xff0c;即把源代码一个一个的 js 文件&#xff0c;打包汇总为一个总文件 bundle.js。 基本配置包括mode指定打包模式&#xff0c;entry指定打包入口&#xff0c;output指定打包输出目录。 另外&#xff0c;由于 webpack默认只能打…

6轴机器人运动正解-逆解控制【1】——三种控制位姿的方式

概览&#xff1a; 通过运动学正解控制机器人运动通过运动学逆解控制机器人运动一个简单的物体搬运&#xff08;沿轨迹运动&#xff09; 后续会陆续更新&#xff08;本例仅供学习交流用&#xff09; 一、6轴机器人 二、运动正解控制 通过修改各个轴的角度&#xff0c;实现末…

宠物互联网医院系统:数字化呵护你爱宠的新时代

宠物互联网医院系统正在为宠物主人提供一种前所未有的数字化健康护理体验。通过结合创新技术&#xff0c;这一系统旨在让宠物医疗变得更加便捷、智能和个性化。让我们深入探讨宠物互联网医院系统的技术核心&#xff0c;以及如何应用代码为你的爱宠提供最佳关怀。 1. 远程医疗…

linux clickhouse 安装

1、官网下载clickhouse安装包 下载地址&#xff0c; clickhouse分lts和stable版本&#xff0c;lts是长期版本&#xff0c;一般选择安装lts版本。 其中clickhouse-server是clickhouse服务&#xff0c;就是用来访问数据存储数据&#xff0c;clickhouse-client是用来通过命令访问数…

Java中的HTTPS通信

在Java中实现HTTPS通信&#xff0c;主要涉及到SSL/TLS协议的使用&#xff0c;用于提供数据传输的安全性。下面我们将深入探讨如何使用Java进行HTTPS通信。 一、基本概念 HTTPS&#xff0c;全称为Hypertext Transfer Protocol Secure&#xff0c;是HTTP的安全版本。它使用SSL/…

CSS之高度塌陷和外边距塌陷

目录 1.高度塌陷&#xff08;原因&#xff0c;如何解决&#xff09; 【概念介绍】 【解决办法】 【概念介绍-BFC】 【拓展-BFC的触发条件】 2.外边距塌陷 &#xff08;原因&#xff0c;如何解决&#xff09; 【概念介绍】 【两种情况】 1.相邻块元素 2.嵌套块元素 【…

码龙乘风 - AI助你不断升级的编程体验

这几年,人工智能(AI)技术飞速发展,现已深入到编程工具之中,助力程序员不断提高工作效率。下面我就谈谈 AI 给编程带来的一些实用功能,以及如何利用好这些功能,让编码变得更轻松、高效。 一、AI辅助编写代码 现在已有不少编程工具加入了AI助手,可以在编码时自动补全代码、提示…

中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备1

接前一篇文章&#xff1a;中移&#xff08;苏州&#xff09;软件技术有限公司面试问题与解答&#xff08;0&#xff09;—— 面试感悟与问题记录 本文参考以下文章&#xff1a; VirtIO实现原理——PCI基础 VirtIO实现原理——virtblk设备初始化 特此致谢&#xff01; 本文对…

eNSP学习——VLAN基础配置及Access接口

目录 原理概述 实验内容&#xff1a; 实验目的&#xff1a; 实验步骤&#xff1a; 实验拓扑 配置过程 实验编址 基本配置 创建vlan 配置Access接口 原理概述 早期的局域网技术是基于总线型结构的。总线型拓扑结构是由一根单电缆连接所有主机&#xff0c;就导致所…

微认证 openEuler社区开源贡献实践

文章目录 1. 开源与开源社区2. openEuler 社区概述3.参与openEuler社区贡献4.openEuler软件包开发Linux软件管理——源码编译 1. 开源与开源社区 Richard Matthew Stallman&#xff0c;1983年9月推出GNU项目&#xff0c;并发起自由软件运动(free software movement或free/open…

《Linux高性能服务器编程》笔记07

Linux高性能服务器编程 本文是读书笔记&#xff0c;如有侵权&#xff0c;请联系删除。 参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 文章目录 Linux高性能服务器编程第14章 多线程编程14.1 Linux线程概述14…

7.FPR/TNR-机器学习模型性能的常用的评估指标

FPR/TNR指标在机器学习中并不常用&#xff0c;因此&#xff0c;此处简单的介绍相应的概念和公式&#xff0c;帮助大家全面了解机器学习相关的评估指标。 一.FPR/TNR的定义和公式 在机器学习中&#xff0c;性能评估是了解模型在处理任务中的效果的关键部分。FPR&#xff08;Fa…

内网穿透、远程桌面、VPN的理解

最近在研究内网穿透的相关技术&#xff0c;然后回想起一些相关的技术&#xff0c;比如说要远程桌面公司的电脑&#xff0c;VPN连入内网等。然后想着在此处记录一下&#xff0c;各个的区别&#xff0c;这个纯粹是从技术层面的理解&#xff0c;此处不详细解释怎么去实现或者用什么…

el-table在鼠标移动到单元格时变为下拉框,否则是普通文本

el-table将多个单元格改为下拉框&#xff0c;导致渲染卡顿&#xff0c;解决方法在鼠标移动到单元格时变为下拉框&#xff0c;否则是普通文本 <el-table-column label"显示方向" width"150px" align"center" key"direction" prop&q…

Jmeter分布式压测过程常见问题

1、JMeter分布式压测试&#xff0c;结果树响应数据为空 解决&#xff1a;打开主控机的jmeter-bin,打开jmeter-properties,将modeStandard 前面的#去掉&#xff0c;保存重启jmeter 2、JMeter压力测试报Address already in use: connect错误 方法一&#xff1a; cmd中&#x…

SpringBoot实现热部署

一、热部署&#xff08;Hot Swap&#xff09; 从Java1.4起&#xff0c;JVM引入了HotSwap&#xff0c;能够在Debug的时候更新类的字节码。所以使用热部署&#xff0c;可以实现修改代码后&#xff0c;无须重启服务就可以加载修改的代码&#xff0c;但是它只能用来更新方法体。 实…