Selenium selenium 定位总结

周小丽 · 2022年01月27日 · 最后由 大桥 回复于 2022年01月28日 · 4918 次阅读

xpath 有两种表示方法,绝对路径和相对路径,绝对路径是指从根开始,以/开始,如/html/body/div,相对路径是指在一个路径下,另外的路径以这个路径作为参照,以//开始。测试时,一般使用相对路径查找元素 (安装 ChroPath 插件,可以查找 xpath 路径)。
xpath 用法来源于:https://www.cnblogs.com/purelavender/p/14512530.html

怎么提高 selenium 脚本的自动化执行效率?

1、优化测试用例,尽可不使用 sleep,减少使用 ImplicitlyWait,而使用 selenium 的 wait/FluentWait,这样可以优化等待时间
2、使用 selenium grid,通过 testng 实现并发执行
3、 针对一些不稳定的动态控件通过 JS 实现操作
4、重载 testng 的 listener 实现 retry 机制,提高测试用例成功率

xpath 基本用法:

  1、属性定位 表示方法://标签名 [@ 属性名=属性值] ,通过单一的属性即可查找到元素。如:查找输入文本框,//input[@id='kw']
  

  2、and 组合属性定位 表示方法://标签名 [@ 属性名 1=属性值 and 属性名 2=属性值],当单一属性无法定位唯一元素时,可以组合多个属性进行查找。如:查找输入文本框,//input[@name='wd' and @class=s_ipt]
  

  3、通过父元素找子元素 表示方法: //父元素/子元素,当查找的元素没有特征属性时,其父元素有特征属性时,可以通过其父元素往下查找。如:查找输入文本框,//span[@id='s_kw_wrap']/input
  

  4、通过祖先元素找子孙元素 表示方法://祖先元素//子孙元素,当查找的元素没有特征属性时,其祖先元素有特征属性时,可以通过其祖先元素往下查找。如:查找输入文本框,//span[@id='s_kw_wrap']//input
  

  5、通过子元素找父元素 表示方法://子元素/..,当查找的元素没有特征属性,其子元素有特征属性时,可以通过其子元素往上查找。如:查找输入文本框的父元素,//input[@id='kw']/..
  

  6、通过文本定位,表示方法://标签名 [text()=文本内容](text 前不需要加 @ 符号),经常和 contains() 组合使用。如,定位【新闻】对应的 a 标签,//a[text()='新闻']
  

  7、通过 contains 模糊匹配定位,表示方法://标签名 [contains(属性或文本, 内容)]。如,定位页面中的【设置】元素,//span[contains(@name, 'tj')]
  

  8、通过索引 [] 定位 (注意:1、加括号;2、索引从 1 开始),如,定位【学术】对应的 a 标签,(//a[@class='mnav c-font-normal c-color-t'])[7]
  

  9、常用的轴运算,表示方法:轴关系::标签名称
  ancestor:当前元素的所有祖先元素(父、祖父等),如:通过【设置】查找其父级 div 元素,//span[@id='s-usersetting-top']//ancestor::div[@id='u1']
  

  following-sibling:当前元素之后的所有同级元素,如:查找【直播】之后的同级元素,//a[contains(text(), '直播')]//following-sibling::a
  

  preceding-sibling:当前元素之前的所有同级元素,如:查找【直播】之前的同级元素,//a[contains(text(), '直播')]//preceding-sibling::a
  

selenium 之 CSS 定位汇总


定位输入框
一:单一属性定位
1:type selector
driver.find_element_by_css_selector('input')

2:id 定位
driver.find_element_by_css_selector('#kw')

3:class 定位
driver.find_element_by_css_selector('.s_ipt')

4:其他属性定位
driver.find_element_by_css_selector('[name='wd']')
driver.find_element_by_css_selector("[type='text']")

二:组合属性定位

1:id 组合属性定位
driver.find_element_by_css_selector("input#kw")

2:class 组合属性定位
driver.find_element_by_css_selector("input.s_ipt")

3:其他属性组合定位
driver.find_element_by_css_selector("input[name='wd']")

4:仅有属性名,没有值也可以
driver.find_element_by_css_selector("input[name]")

5:两个其他属性组合定位
driver.find_element_by_css_selector("[name='wd'][autocomplete='off']")

三种等待的用法

ImplicitlyWait(隐式等待)
driver.implicitly_wait(10) # 设置隐式等待时间为 10s
是指对整个页面的加载,隐式等待在 driver 的整个生命周期内都有效。
也就是说,driver 在没有被 close() 之前,定位每个元素时,都会有隐式等待的 10s,也就是说,只需要设置一次,所有的元素都可有最多 10s 的等待加载的时间
可是隐式等待依然存在一个问题,那就是程序会一直等待整个页面加载完成,也就是通常状况下你看到浏览器标签栏那个小圈再也不转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,可是由于个别 js 之类的东西特别慢,我仍得等到页面所有完成才能执行下一步。因此,这里 webdriver 提供了一种更加智能的等待方式:显示等待 spa

Explicit Wait(显式等待)
wait = WebDriverWait(driver, 10) # 设置显示等待时间为 10s
element = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#kw')))# 判断条件
element.send_keys("Python")
弥补了 implicit wait 的不足,能够经过判断一些条件,再去决定是否等待下去,显示等待是一种智能程度较高的等待方式,能够有效的加强脚本的健壮性

Fluent wait(流畅等待,即显式等待的一种)
可以设置自己的方法去处理各种等待的问题。

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
                //最大等待时间是60秒
                   .withTimeout(60, TimeUnit.SECONDS)
             //每隔两秒去找一次元素ele1是否在页面显示
                   .pollingEvery(2, TimeUnit.SECONDS)
             //并且忽略NoSuchElement异常
                   .ignoring(NoSuchElementException.class);
             //ele1定位过程使用了对象wait
        WebElement ele1 = wait.until(new Function<WebDriver, WebElement>() {
             //一个等待的条件
             public WebElement apply(WebDriver driver) {
               return driver.findElement(By.id("xxxxxxx"));
             }       
           });

上面创建了一个 FlentWait 类的一个对象 wait,最大等待时间是 60 秒,每隔两秒去找一次元素 ele1 是否在页面显示。并且忽略 NoSuchElement 异常。下面的元素定位,ele1 定位过程使用了对象 wait,然后里面新建了一个函数,只需要把这个函数当做是一个等待的条件就很好理解。

共收到 2 条回复 时间 点赞

FluentWait 这个第一次知道,学习了。

我从 selenium 投奔到 playwright 阵营了,真香

周小丽 关闭了讨论 06月14日 16:23
周小丽 重新开启了讨论 06月14日 16:23
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册