相对定位历史

  • 2021-10-13 发布的 selenium 4.0 开始引入,selenium 3.X是没有的
implement relative locator for find_element (#9902)
  • 4.10维护了下
Improve near relative locator behavior (#11290)

其他都是文档、异常信息方面的处理

实例演示

D:\selenium\demo\relative.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>relative</title>
</head>
<body>
DATE:<input id="date" type="text">
USER:<input id="username" type="text"><br>
CODE:<input id="code" type="text">
PASS:<input id="password" type="text">
</body>
</html>

如下界面

实例代码

from selenium.webdriver.common.by import By
from selenium.webdriver.support.relative_locator import locate_with from selenium import webdriver
from time import sleep
driver = webdriver.Chrome()
driver.get(r'D:\selenium\demo\relative.html')
ele_date = driver.find_element('id','date')
ele_code = driver.find_element('id','code')
ele_user = driver.find_element('id','username')
ele_password = driver.find_element('id','password') driver.find_element(locate_with(By.CSS_SELECTOR, "input").above(ele_code)).send_keys('code aboe')
driver.find_element(locate_with(By.CSS_SELECTOR, "input").below(ele_user)).send_keys('user below')
driver.find_element(locate_with(By.CSS_SELECTOR, "input").to_left_of(ele_password)).send_keys('pass left')
driver.find_element(locate_with(By.CSS_SELECTOR, "input").to_right_of(ele_date)).send_keys('date right')
driver.find_element(locate_with(By.CSS_SELECTOR, "input").near(ele_code)).send_keys('code near')

执行效果

相关源码说明

find_element

在find_element的源码中有这么一段

    def find_element(self, by=By.ID, value=None) -> WebElement:
if isinstance(by, RelativeBy):
elements = self.find_elements(by=by, value=value)
if not elements:
raise NoSuchElementException(f"Cannot locate relative element with: {by.root}")
return elements[0]

也就是说你传入的by不仅仅可以是下面这8个,还可以是RelativeBy对象

class By:
"""
Set of supported locator strategies.
""" ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"

那如果是RelativeBy对象的话,会去调用find_elements,self.find_elements(by=by, value=value)

    def find_elements(self, by=By.ID, value=None) -> List[WebElement]:
if isinstance(by, RelativeBy):
_pkg = '.'.join(__name__.split('.')[:-1])
raw_function = pkgutil.get_data(_pkg, 'findElements.js').decode('utf8')
find_element_js = f"return ({raw_function}).apply(null, arguments);"
return self.execute_script(find_element_js, by.to_dict())

if语句下的2行代码就是在加载findElements.js

最后两句就是构造一个js然后去执行它,细节就不追究了

RelativeBy

这个class位于selenium\webdriver\support\relative_locator.py

class RelativeBy:
def __init__(self, root: Dict[By, str] = None, filters: List = None):
self.root = root
self.filters = filters or [] def above(self, element_or_locator: Union[WebElement, Dict] = None) -> "RelativeBy":
if not element_or_locator:
raise WebDriverException("Element or locator must be given when calling above method") self.filters.append({"kind": "above", "args": [element_or_locator]})
return self

这个类提供了6个实例方法:above below to_left_of to_right_of near

可以看到RelativeBy对象的实例化需要2个参数,一个是root:dict类型,一个是filters : 列表类型

可以看到above这样的方法其实没做啥,关键是对self.filters的一个处理,增加一个对应kind(与方法同名)和args,这个args操作你要去参考的元素的定位器或WebElement

locate_with

在实例代码中,我们用到了locate_with这个函数,这个函数跟RelativeBy在同一个文件中

代码如下

def locate_with(by: By, using: str) -> "RelativeBy":
assert by is not None, "Please pass in a by argument"
assert using is not None, "Please pass in a using argument"
return RelativeBy({by: using})

可以看到它确实是返回了一个RelativeBy的实例对象

而它的用法跟我们的find_element就一致了,唯一的不同就是参数名,这边是using,find_element是value

为何用它的另一方面原因是在RelativeBy的doc中这样的一段描述

        Example:
lowest = driver.find_element(By.ID, "below") elements = driver.find_elements(locate_with(By.CSS_SELECTOR, "p").above(lowest))

说在最后

这东西我在工作中没有用过,因为它出生后我就进入了...

使用过一些常见去测试它的效果,并不理想,不过是在早期的版本中做的,现在不清楚是否好用一些

溯源的话应该可以追溯到js中吧,有空找下,或者哪个大佬知道的可以指点下

谈谈selenium4.0中的相对定位的更多相关文章

  1. 谈谈PBOC3.0中使用的国密SM2算法

    转载请注明出处 http://blog.csdn.net/pony_maggie/article/details/39780825 作者:小马 一 知识准备 SM2是国密局推出的一种他们自己说具有自主 ...

  2. Core 1.0中的管道-中间件模式

    ASP.NET Core 1.0中的管道-中间件模式 SP.NET Core 1.0借鉴了Katana项目的管道设计(Pipeline).日志记录.用户认证.MVC等模块都以中间件(Middlewar ...

  3. (转)谈谈RTP传输中的负载类型和时间戳

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://ticktick.blog.51cto.com/823160/350142 最近被 ...

  4. 谈谈Vue/React中的虚拟DOM(vDOM)与Key值

    谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...

  5. Fixed-Length Frames 谈谈网络编程中应用层(基于TCP/UDP)的协议设计

    http://blog.sina.com.cn/s/blog_48d4cf2d0101859x.html 谈谈网络编程中应用层(基于TCP/UDP)的协议设计 (2013-04-27 19:11:00 ...

  6. 【FFMPEG】谈谈RTP传输中的负载类型和时间戳

    谈谈RTP传输中的负载类型和时间戳 最近被RTP的负载类型和时间戳搞郁闷了,一个问题调试了近一周,终于圆满解决,回头看看,发现其实主要原因还是自己没有真正地搞清楚RTP协议中负载类型和时间戳的含义.虽 ...

  7. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  8. [译] C# 5.0 中的 Async 和 Await (整理中...)

    C# 5.0 中的 Async 和 Await [博主]反骨仔 [本文]http://www.cnblogs.com/liqingwen/p/6069062.html 伴随着 .NET 4.5 和 V ...

  9. Spring.Net在Mvc4.0中应用的说明

    案例Demo:http://yunpan.cn/cJ5aZrm7Uybi3 访问密码 414b Spring.Net在Mvc4.0中应用的说明 1.引用dll 2.修改Global文件 (Spring ...

  10. WCF学习之旅—WCF4.0中的简化配置功能(十五)

    六 WCF4.0中的简化配置功能 WCF4.0为了简化服务配置,提供了默认的终结点.绑定和服务行为.也就是说,在开发WCF服务程序的时候,即使我们不提供显示的 服务终结点,WCF框架也能为我们的服务提 ...

随机推荐

  1. Jenkins快速入门部署+实践

    安装 方法一 Jenkins中文网下载jenkins.war 方法二 直接从http://mirrors.jenkins-ci.org/war/latest/jenkins.war下载最新的war包, ...

  2. Maven配置UTF8,JDK版本

    <!-- 局部jdk配置,pom.xml中 --> <build> <plugins> <plugin> <groupId>org.apac ...

  3. C语言变量常量

    目录 前言 一.数据类型 1.整形 2.浮点型 3.字符型 二.变量的操作 1.变量的创建 2.变量的使用 2.1 变量的赋值 2.2 变量的加减 2.3 变量的隐式类型转换 2.4 强制类型转换 3 ...

  4. CMDB 相关

    CMDB 术语 CI(配置项) 配置管理解决方案(如CMDB)中的基本有形或无形实体. 为了交付IT服务而需要管理的任何组件. 通常包括IT服务.硬件.软件.架构.人员和正式文档(如流程文档和sla) ...

  5. 2021-7-6 new tcpip

    using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Ne ...

  6. Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用

    Unity UGUI的PhysicsRaycaster (物理射线检测)组件的介绍及使用 1. 什么是PhysicsRaycaster组件? PhysicsRaycaster是Unity UGUI中的 ...

  7. 磁盘问题和解决: fsck,gdisk,fdisk等

    错误: Resize inode not valid 对于gpt分区的硬盘一般fsck只能检查分区, 不能用于检查整个硬盘, 但是如果对硬盘设备运行时遇到这样的错误 $ sudo fsck -n /d ...

  8. C# 处理 csv 文件中的双引号

    C# CSV 双引号处理 直接上代码,自己写的,有问题可以随时联系 // 没有保证所有的都能对上,目前只处理了自己所遇见的格式 public static string[] SplitStr(stri ...

  9. 69.9K Star,最强开源内网穿透工具:frp

    作为一名开发者,有很多场景需要用到内网穿透,比如:我们在接入一些大平台做第三方应用时,在本地开发微信公众号工具的时候需要让微信平台能否访问到本地提供的接口.除此之外,还有很多其他场景,也会用到,比如: ...

  10. 实现无限存储:基于JuiceFS 创建 Samba 和 NFS 共享

    随着企业数据量的持续增长,存储容量需求日益增大.如何采用没有容量上限的云存储替换本容量有限的本地磁盘,已成为广泛的需求和共识.特别是在企业中常用的 Samba 和 NFS 共享,如果能够使用云存储作为 ...