首页 > 其他分享 >谈谈selenium4.0中的相对定位

谈谈selenium4.0中的相对定位

时间:2023-10-20 10:44:07浏览次数:34  
标签:locate 定位 selenium4.0 self driver RelativeBy element 谈谈 find

相对定位历史

  • 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中吧,有空找下,或者哪个大佬知道的可以指点下

标签:locate,定位,selenium4.0,self,driver,RelativeBy,element,谈谈,find
From: https://www.cnblogs.com/wuxianfeng023/p/17776496.html

相关文章

  • 开源项目 | 美团开源监控告警服务,Java 开发的实时应用监控平台,能够帮助开发者快速定位
     一、项目概述        CAT是基于Java开发的实时应用监控平台,为美团点评提供了全面的实时监控告警服务。        CAT作为服务端项目基础组件,提供了Java,C/C++,Node.js,Python,Go等多语言客户端,已经在美团点评的基础架构中间件框架(MVC框架,RPC框架,数据......
  • Python Traceback:异常信息定位
    一、traceback模块简介traceback模块是Python标准库中的一个模块,提供了一些函数和类,用于获取和处理异常的跟踪信息。它可以帮助我们定位异常信息所在的代码位置,从而更好地调试和修复程序。 二、获取异常跟踪信息1.traceback.format_exc()函数在异常处理中,我们经常需要获取......
  • Oracle中如何根据查询sql片段定位查询客户端主机地址
    --1.根据sql片段获取sql_id--select*fromv$sqlwherelast_active_time>sysdateandsql_textlike'%ZL0204_03r%';selectsql_id,modulefromv$sqlwherelast_active_time>sysdateandsql_textlike'%ZL0204_03%';--2.根据sql_id查询sid......
  • 热块及毛刺问题定位
    1.查看活动会话最高的时间点和SAMPLE_IDselectsample_id,sample_time,count(*)fromv$active_session_historyawheresample_timebetweento_date('xxxxxxxxx','yyyymmddhh24miss')andto_date('xxxxxxxxx','yyyymmddhh24miss')group......
  • RTK高精度定位安全帽-UWB室内定位/GPS定位智能安全帽技术方案
    高精度RTK定位安全帽是一种综合性解决方案,结合了先进的GPS定位技术、物联网技术、移动数据传输和智能执法管理。相较于传统的定位安全帽,它提供了更高的定位精度、更强大的数据处理能力和更全面的施工过程记录,对公共安全领域有着实质性的积极影响。该安全帽采用厘米级RTK定......
  • 定位元素封装find_element(增加显性等待等)
     封装#find_elementUtil.pyimportosimporttimefromselenium.webdriver.supportimportexpected_conditionsasECfromappium.webdriver.common.appiumbyimportAppiumByfromselenium.webdriver.support.waitimportWebDriverWait#frombaseimportdriver_......
  • 定位控制元素水平垂直居中
    浏览器中盒子的位置1.使用绝对元素,相对于浏览器第一窗口进行50%的距离设置,盒子会移动到第四象限; 再使用外边距设置让盒子移动到中间位置(注意正负值的设置)*{margin:0;padding:0;}div{width:200px;height:200px;......
  • vue框架,input相同标签如何定位-label定位
    一、问题提出:后台前端框架改版,之前是angularjs,现在用vue,导致input标签定位失败,只能定位到第一个input标签,查看后台源代码发现这两个标签是一模一样,如下图:二、问题思考过程1.为什么以前的版本可以定位成功,而现在的就定位不了啦查阅之前版本的这部分定位代码,发现原来的框架是......
  • 定位SQL慢查询
    一、概念MySQL的慢查询(慢查询日志):是MySQL提供的一种日志记录,用来记录在MySQL中响应时间超过阈值的语句。具体环境中,运行时间超过long_query_time值的SQL语句,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是记录运行10秒以上的语句。默认情况下,MySQL数据库并不启......
  • 使用 KubeSkoop exporter 监测和定位容器网络抖动问题
    作者:遐宇、溪恒本文是8月17日直播的文字稿整理,文末可观看直播回放。除去文章内容外,还包括针对实际网络问题的实战环节。容器网络抖动问题发生频率低,时间短,是网络问题中最难定位和解决的问题之一。不仅如此,对Kubernetes集群内的网络状态进行日常的持续性监测,也是集群运维中很......