首页 > 其他分享 >Selenium3自动化测试实战--第4章 WebDriver API 2--显示等待和隐式等待

Selenium3自动化测试实战--第4章 WebDriver API 2--显示等待和隐式等待

时间:2022-11-18 23:13:40浏览次数:45  
标签:WebDriver webdriver -- selenium driver element import 等待

4.7 设置元素等待

分 显式等待和隐式等待

4.7.1 显式等待

是Webdriver等待某个条件成立时则继续执行,否则在达到最大时长时抛出超时异常

官网原文: 显示等待是selenium客户可以使用的命令式过程语言。它们允许您的代码暂停程序执行,或冻结线程,直到满足通过的条件。这个条件会以一定的频率一直被调用,直到等待超时。这意味着只要条件返回一个假值,它就会一直尝试和等待。

由于显示等待允许您等待条件的发生,所以它们非常适合在浏览及其DOM和Webdriver脚本之间同步状态。

为了弥补我们之前的错误指令集,我们可以使用等待来让FindElement调用等待直到脚本中动态添加的元素被添加到DOM中。 但官网中的例子代码,跑不通。

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait  
# from selenium.webdriver.support.wait import WebDriverWait  # 官网用的,试验了,也能用
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get('https://www.baidu.com')

element = WebDriverWait(driver,5,0.5).until(
    EC.visibility_of_element_located((By.ID,'kw'))  # 该方法只允许1个参数,所以(By.ID,'kw')应该括起来做为1个参数
)
element.send_keys('selenium')

driver.quit()

WebDriverWait是一种等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在。如果超出设置时间仍检测不到,则抛出异常。

WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)

WebDriverWait()一般与until() 或 until_not()方法配合使用。

until() 调用该方法提供的一个驱动程序作为一个参数,直到返回值为True

而until_not()则直到返回值为False

本来想通过在visibility_of_element_located()后面加上print(time.time()),验证WebDriverWait,但发现这样写会千万语法问题。

 

文中说,超时后的异常信息,默认情况下抛出NoSuchElementException异常。但通过下面的试验,看到抛出的是TimeoutException。

如果将kw改成k1w,再执行,就会定位不到元素,超过5秒后,抛出超时异常

raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message: 

excepted_conditions类提供的预期条件判断方法

方法   说明
  title_is   判断当前页面的标题是否等于预期
  title_contains   
  presence_of_element_located   判断元素是否被加在DOM中,并不代表可见
  visibility_of_element_located   判断元素是否可见
  visibility_of   与上一个方法作用相同,上一个方法的参数为定位,该方法接收的参数为定位后的元素
  text_to_be_present_in_element   判断某元素中的text是否包含预期的字符串
  text_to_be_present_in_element_value   判断某元素的value属性是否包含预期的字符串
  frame_to_be_available_and_switch_to_it   判断该表单是否可以切换进去,如果可以,返回True并且切换进去
  element_bo_be_selected   判断某个元素是否被选中,一般用在下拉列表中
  alert_is_present   判断页面上是否存在alert
from time import sleep,ctime
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get('https://www.baidu.com')

print(ctime())
for i in range(10):
    try:
        el = driver.find_element(By.ID,'kw22')
        if el.is_displayed():   # 使用is_displayed()确认元素是否可见
            break
    except:
        pass
    sleep(1)
else:
    print('time out')
print(ctime())

driver.quit()

4.7.2 隐式等待

implicitly_wait()

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import ctime
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()
driver.implicitly_wait(10)  ### 
driver.get('https://www.baidu.com')

try:
    print(ctime())
    driver.find_element(By.ID,'kw22').send_keys('selenium')
except NoSuchElementException as e:
    print(e)
finally:
    print(ctime())
    driver.quit()

implicitly_wait()的参数是时间,单位秒。首先,这个参数并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它会等待页面上所有元素。当脚本执行到某个元素时,如果元素存在,则继续执行;如果定位不到元素,则它将以轮询的方式不断地判断元素是否存在。假设在第6s定位到了元素,则继续执行,若直到超出设置时间还没有定位到元素,则抛出异常。 感觉这段话的描述,与显示等待,没有什么区别。不知道是我理解错误,还是描述错误。

官网中对隐式等待的描述是:

  通过隐式等待,webdriver在试图查找 任何 元素时在一定时间内轮询DOM(这倒是与上述一个意思)。当网页上的某些元素不是立即可用并且需要一些时间来加载是是很有用的。

默认情况下隐式等待元素出现是禁用的,它需要在单个会话的基础上手动启用。将显示等待和隐式等待混合在一起会导致意想不到的结果,就是说即便元素可用或条件为真也要等待睡眠的最长时间。

  警告:不要混合使用隐式和显式等待。这样会导到不可预测的等待时间。例如,将隐式等待设置为10s,将显式等待设置为15s,可能会导致在20S后发生超时。

隐式等待是告诉webdriver如果在查找一个或多个不是立即可用的元素时轮询DOM一段时间。默认设置为0,表示禁用。一旦设置好,隐式等待就会被设置为会话的生命周期。

隐式等待与显式等待的区别,有的网文说,隐式等待在等待时间内浏览器会不断刷新页面去等待。我觉得这不可能。因为使用隐式等待时,没有发现页面刷新的现象。......

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import ctime,sleep
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()

driver.implicitly_wait(10)
driver.get('https://www.baidu.com')
s_word = 'kw22'

for i in range(10):
    if i < 3:
        print(i," ",s_word," ",ctime()," ",end="")  ##不换行 end=''              
        try:
            el = driver.find_element(By.ID,s_word)
            if el.is_displayed():
                break
        except:
            print(ctime()," 定位不到元素")
            i = i +1
            continue 
    elif i == 3:
        s_word = 'kw'
        print(i," ",s_word," ",ctime())
        driver.find_element(By.ID,s_word).send_keys('selenium')
    else:
        break
    print("验证continue时,该语句的执行情况")
        
sleep(5)
driver.quit()

将continue改成pass后

从上面的代码,可以得到2点:

1 设置了隐式等待为10秒,当try进行元素定位时,只有超过10秒仍定位不到,才会向下走其它代码。

2 定位失败时,当用continue时,不再执行后面的print代码,直接执行下一次迭代,只有当下次迭代因为if条件不满足,没有执行continue时,而是执行了elif时才同时执行了print;当用pass时,每次迭代都会执行后面的print;同时如果运行了break,则是停止上一层(如果有多层循环)的所有循环迭代。

第2点,没问题了。但第1点,定位元素只有1条,如果是有多条定位元素,是每条都10秒,还是一起10秒?

发现是一起10秒

如果将2个定位语句分开呢?因为try中如果前面的第1条定位如果发生异常,后面的第2条定位应该是不会执行异常。

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import ctime,sleep
from selenium.common.exceptions import NoSuchElementException

driver = webdriver.Chrome()

driver.implicitly_wait(10)
driver.get('https://www.baidu.com')
s_word = 'kw22'
s_word2 = 'su22'

for i in range(10):
    if i < 3:
        print(i," ",s_word," ",ctime()," ",end="")  ##不换行 end=''              
        try:
            el = driver.find_element(By.ID,s_word)            
            if el.is_displayed():
                break
        except:
            print(ctime()," 定位不到第1个元素",end='')
            try:
                el2 = driver.find_element(By.ID,s_word2)
                if el2.is_displayed():
                    break
            except:
                print(' ',ctime()," 定位不到第2个元素")
                i = i +1
                pass
        
    elif i == 3:
        s_word = 'kw'
        s_word2 = 'su'
        print(i," ",s_word," ",s_word2," ",ctime())
        driver.find_element(By.ID,s_word).send_keys('selenium')
        driver.find_element(By.ID,s_word2).click()
    else:
        break
    print("验证pass时,该语句的执行情况")
        
sleep(5)
driver.quit()

由此可知,每条定位元素的语句的执行,都会最长进行10秒。

除了上面的2种等待,还有 强制等待(sleep()), 和官网上提到的 流畅等待。但看着跟显式等待是一样的啊

driver = Firefox()
driver.get("http://somedomain/url_that_delays_loading")
wait = WebDriverWait(driver, timeout=10, poll_frequency=1, ignored_exceptions=[ElementNotVisibleException, ElementNotSelectableException])
element = wait.until(EC.element_to_be_clickable((By.XPATH, "//div")))

 

标签:WebDriver,webdriver,--,selenium,driver,element,import,等待
From: https://www.cnblogs.com/guohui2022/p/16894205.html

相关文章

  • python学习笔记(二)
    一、数据类型python里面直接auto了,跟c有很大不同,基本上由编译器自动检测赋值内容,但也可以手动确定。 只不过有挺多其他的函数很方便var1=100var2=200var3=300......
  • ES6之rest参数
     (1)//ES6引入rest参数,用于获取函数的实参,用来代替arguments//ES5获取实参的方式functiondate(){console.log(arguments);......
  • day18-web工程路径
    web工程路径配置tomcat运行快捷键tomcat启动的默认快捷键时shift+f10,可以自定义配置:file-setting-keymap-搜索run,找到右边写有shift+f10的选项,右击选择addkeyboardsh......
  • 不背锅运维:解读docker容器网络
    docker的网络模型如下图:[root@test-a-docker01 ~]# ifconfigdocker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500        inet 172.17.0.1......
  • elementUI tree树节点文字超出时省略或折行 样式
    文字超出时折行::v-deep.tree{width:100%;.el-tree-node{white-space:normal;.el-tree-node__content{height:100%;a......
  • 【CSS】动态DOM节点的classList属性
    动态DOM节点的classList属性为div元素动态添加class:element.classList定义和用法classList属性返回元素的类名,作为DOMTokenList对象。该属性用于在元素中添加,......
  • RESTful API规范
    1.url链接一般都采用https协议进行传输http:数据明文传输https:数据加密传输http+ssl2.用api关键字标识接口url:https://api.baidu.comhttps://www.b......
  • Opencat-B——串联动作组(爬台阶)
    导航在这里:Arduino四足开源机器猫通过把机器猫的Posture串联起来,可以实现炫酷的组合动作或者功能性动作(爬楼梯)。我们需要去在instinct.h文件里自定义并且一个一个尝试具体......
  • 白泽六足机器人_arduino_v1——零件准备
    导航在这里:白泽六足机器人_arduino_v11.主控板x1Baize_ServoDriver_esp8266​或者Baize_ServoDriver_esp32如下图左边为 Baize_ServoDriver_esp8266;右边为Baize_ServoDriv......
  • Arduino四足开源机器猫-Opencat(导航贴)
    本内容由我和小伙伴共同编写,未经授权,谢绝转载!1.项目介绍2.组装调试教程(一)Opencat-F(1)资料地址(包含程序代码&&3D打印图纸):链接:https://pan.baidu.com/s/1gTTPReQL5uUkNbS4u-Po......