【selenium】强制等待,隐式等待,显式等待

在实际使用selenium或者appium时,等待下个等待定位的元素出现,特别是web端加载的过程,都需要用到等待,而等待方式的设置是保证脚本稳定有效运行的一个非常重要的手段,在selenium中(appium通用)常用的等待分为显示等待WebDriverWait()、隐式等待implicitly_wait()、强制等待sleep()三种,下面我们就分别介绍一下这三种等待的区别

强制等待

sleep(): 强制等待,设置固定休眠时间。脚本的执行过程中执行 sleep()后线程休眠。

隐式等待

implicitly_wait():隐式等待,是设置的全局等待。设置等待时间,是对页面中的所有元素设置加载时间,如果超出了设置时间的则抛出异常。隐式等待可以理解成在规定的时间范围内,浏览器在不停的刷新页面,直到找到相关元素或者时间结束。

# 导包-selenium
from selenium import webdriver
# 导入时间包
from time import  sleep
# 实例化对象-火狐浏览器
driver=webdriver.Firefox()

# 调用隐式等待
driver.implicitly_wait(10)


url="E:\\双元\\Web自动化\\02_其他资料\\注册A.html"
# 打开url
driver.get(url)

driver.find_element_by_css_selector("#userA").send_keys("admin")
driver.find_element_by_css_selector("#passwordA").send_keys("123456")

sleep(3)
# 关闭浏览器
driver.quit()

显式等待

WebDriverWait():显式等待,是针对于某个特定的元素设置的等待时间,在设置时间内,默认每隔一段时间检测一次当前页面某个元素是否存在,如果在规定的时间内找到了元素,则直接执行,即找到元素就执行相关操作,如果超过设置时间检测不到则抛出异常。默认检测频率为0.5s,默认抛出异常为:NoSuchElementException

实现步骤

1. 导包 等待类         --> from selenium.webdriver.support.wait import WebDriverWait
2. 导包 判断条件     --> from selenium.webdriver.support import expected_conditions as EC
                        (将expected_conditions 通过as关键字起个别名:EC)
3. WebDriverWait(driver, timeout, poll_frequency=0.5)
        1). driver:浏览器对象
        2). timeout:超时的时长,单位:秒
        3). poll_frequency:检测间隔时间,默认为0.54. 调用方法 until(method):直到..1). method:调用EC.presence_of_element_located(element)
                    element:调用By类方法进行定位
# 导包-selenium
from selenium import webdriver
# 导入显示等待类
from selenium.webdriver.support.wait import WebDriverWait
# 导入预期条件类 as 关键字起个别名为:EC
from selenium.webdriver.support import expected_conditions as EC
# 导入By类
from selenium.webdriver.common.by import By
# 导入时间包
from time import  sleep
# 实例化对象-火狐浏览器
driver=webdriver.Firefox()
url="E:\\双元\\Web自动化\\02_其他资料\\注册A.html"
# 打开url
driver.get(url)
element=WebDriverWait(driver,30).until(EC.presence_of_element_located((By.ID,'userA')))
element.send_keys("admin")

sleep(3)
# 关闭浏览器
driver.quit()

显示等待的第二种调用方式
可以使用lambda表达式,如

WebDriverWait(driver,30).until(lambda x:x.find_element_by_id("kw")).send_keys("yoyo")

#以下代码同理
element=WebDriverWait(driver,30).until(lambda x:x.find_element_by_id("kw"))
element.send_keys("yoyo")

在这里插入图片描述
这里的lambda表达式还可以这样写

def get_element(self, by, locator):
    """
    find alone element
    :param by: eg: id, name, xpath, css.....
    :param locator: id, name, xpath for str
    :return: element object
    """
    try:
        print('[Info:Starting find the element "{}" by "{}"!]'.format(locator, by))
        element = WD(self.driver, self.outTime).until(lambda x: x.find_element(by, locator))  #注意这里的find_element是selemium的内置方法
    except TimeoutException as t:
        print('error: found "{}" timeout!'.format(locator), t)
    else:
        return element

重点看这行代码

element = WD(self.driver, self.outTime).until(lambda x: x.find_element(by, locator)) 

通过看until的源码,我们发现匿名函数lambda传了webdriver对象进去

    def until(self, method, message=''):
        """Calls the method provided with the driver as an argument until the \
        return value is not False."""
        screen = None
        stacktrace = None

        end_time = time.time() + self._timeout
        while True:
            try:
                value = method(self._driver) #发现匿名函数传参driver
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, 'screen', None)
                stacktrace = getattr(exc, 'stacktrace', None)
            time.sleep(self._poll)
            if time.time() > end_time:
                break
        raise TimeoutException(message, screen, stacktrace)

关于lambda表达式的使用说明

# 普通函数定义和调用
def f(x):
return x**2
print f(4)

# lambda表达式匿名函数定义和调用
g = lambda x : x**2
print g(4)

相比隐式等待,显式等待只对指定元素生效,不再是在整个WebDriver生命周期内生效【仅对元素生效】,可以理解成隐式等待就是webdriver级别的显式等待隐式等待也不用等待到页面均加载完毕才开始检查,也是对DOM中单个元素进行依次定位,在规定时间内没有定位到元素就报错。

显式等待和隐式等待本质区别
显示等待在最大超时时间内循环检测,默认0.5s。显示和隐式等待检测的方式都是在web下是执行js,app下是调用uiautomator,所以就算没有全部渲染,也是可以检测的。很多页面都是动态加载的,这期间的每个时刻dom都是完整的,只是在不断改变控件树而已

隐式和显示等待的使用场景

根据WebDriver官网对于 Implicit wait timeout的介绍,隐式等待相当于在WebDriver级别的显式等待,也是相同的策略,使用元素定位进行多次重复查找,一旦找到就返回结果。
Specifies a time to wait for the element location strategy to complete when locating an element

有两种可能需要显式等待:

  • 因为隐式等待一旦找到就会返回结果,而返回结果到脚本,再接收到下一条操作刚才找到的元素的命令需要一段时间。这段时间可能页面已经因为加载后续内容而发生了变化,之前找到的元素也受到了影响,于是操作元素的命令就无法正常执行了。

  • 因为隐式等待只要能定位到元素就会返回,并不能对元素的各种状态进行判断,所以显式等待中丰富的元素属性判断就为有特殊定位需求的情况提供了解决方案。

通常的建议当需要等待时尽量使用显式等待,如果需要隐式等待的话局部使用局部设置,使用完毕复位。不是很推荐隐式等待和显式等待混合使用,详见 Selenium大佬对于不应该混用的解释 (https://stackoverflow.com/questions/15164742/combining-implicit-wait-and-explicit-wait-together-results-in-unexpected-wait-ti/15174978#15174978)

参考链接:
https://ceshiren.com/t/topic/2536
https://testerhome.com/topics/25158

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bug 挖掘机

支持洋子

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值