zoukankan      html  css  js  c++  java
  • 等待机制

    为什么需要等待

     

    当进行自动化测试的时候:

    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.get("https://www.baidu.com")
    driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs")
    driver.find_element_by_id("su").click()
    # import time
    # time.sleep(3)
    driver.find_element_by_link_text("听雨危楼 - 博客园").click()
    driver.quit()

    上述代码如果不睡几秒的话,很可能会报如下报错:

    selenium.common.exceptions.NoSuchElementException

    没有找到标签元素,当然,可能原因是找错了标签,但很可能是这个标签由于网速等原因迟迟没有加载出来,你就直接获取这个标签,很明显是报错,现有的简单粗暴的解决办法就是time.sleep(3),睡几秒,也就是设置线程等待,等这个标签加载出来之后,再去使用。这么着虽然简单,但是相对死板,因为我们不知道这个标签什么时候加载出来,就大概写死睡个几秒,这可以,但如果这个标签在极短的时间内就加载出来了,而你还在睡.......

    所以,我们可以使用selenium提供的两种等待机制:

    • 显式等待
    • 隐式等待

    先来看显式等待机制。

    显式等待机制

     

    上面程序解决报错使用了time模块完成,现在,我们使用selenium的等待机制来完成:

    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    
    driver = webdriver.Chrome()
    driver.get("https://www.baidu.com")
    driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs")
    driver.find_element_by_id("su").click()
    # driver.find_element_by_link_text("听雨危楼 - 博客园").click()
    # 没错,就是下面这行代码
    WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.LINK_TEXT, '听雨危楼 - 博客园'))).click()
    driver.quit()

    selenium提供了 WebDriverWait类实现等待机制。该类接收4个参数来指定等待机制。

    from selenium import webdriver
    from selenium.webdriver.support.ui import WebDriverWait
    driver = webdriver.Chrome()
    WebDriverWait(driver=driver, timeout=10, poll_frequency=0.5, ignored_exceptions=None)

    各参数:

    • driver,浏览器驱动
    • timeout,最长超时时间,单位(秒)
    • poll_frequency,轮询检测时间,也就是每隔多少时间检测一次,默认是0.5秒
    • ignored_exceptions,超时后的异常信息,默认抛出NoSuchElementException

    WebDriverWait类提供了两个方法来完成等待机制:

    • until(self, method, message=''),method为需要提供的驱动程序,直到返回True,用的较多。
    • until_not(self, method, message=''),method为需要提供的驱动程序,直到返回False

    上面用到的method驱动程序为expected_conditions重命名后的EC,并调用其presence_of_element_located方法判断指定元素是否存在。
    expected_conditions模块提供了各种判断:

    • presence_of_element_located判断某个元素是否被加到了dom树里,并不代表该元素一定可见
    • presence_of_elements_located 判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是'column-md-3',那么只要有1个元素存在,这个方法就返回True

    显式等待的另一种写法,首先实例化一个显式等待对象,这样可以在各个地方灵活的调用:

    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver, 10, 0.5)  # 首先实例化一个定制好等待机制的等待对象
    driver.get("https://www.baidu.com")
    driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs")
    driver.find_element_by_id("su").click()
    # WebDriverWait(driver=driver, timeout=10, poll_frequency=0.5, ignored_exceptions=None).until(EC.presence_of_element_located((By.LINK_TEXT, '听雨危楼 - 博客园'))).click()
    wait.until(EC.presence_of_element_located((By.LINK_TEXT, '听雨危楼 - 博客园'))).click()
    driver.quit()

    一般的,推荐上述这种方式,比较灵活嘛。

    隐式等待机制

     

    与显式等待不同的是,隐式等待我们可以直接通过浏览器驱动对象调用,并且用法也相对简单:

    from selenium import webdriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(time_to_wait=10)   # 只需要一个等待超时时间参数
    driver.get("https://www.baidu.com")
    driver.find_element_by_id("kw").send_keys("听雨危楼-cnblogs")
    driver.find_element_by_id("su").click()
    driver.find_element_by_link_text('听雨危楼 - 博客园').click()
    driver.quit()

    implicitly_wait等待时间单位为秒,如上例所示,我们指定了10秒。需要注意的是,隐式与显式等待有明显的区别,隐式等待应用于全局,每当使用driver驱动找某个元素时,隐式等待机制就会被触发(导致测试速度变慢),如果元素存在,则继续执行,否则,它将以轮询的方式判断元素是否定位成功,直至等待超时,抛出错误NoSuchElementException。而显式等待则只是指定某(些)个元素是否存在时执行。

    休眠机制

     

    最后,使用Python提供的休眠机制(也就是time模块啦),这没啥可说的,睡就完了,想在哪等就在哪等.......

    import time
    
    time.sleep(1)

    在等待机制的选择上,我们可以在三种等待机制中灵活选择:

    • 普通(静态页面较多)网页,休眠机制和显式等待机制可以相互搭配,提高效率。
    • 动态页面较多的时候,隐式等待就排上用场了。当然,懒人法则就用隐式等待。一劳永逸.....
  • 相关阅读:
    训练总结
    图论--最短路--SPFA模板(能过题,真没错的模板)
    图论--最短路-- Dijkstra模板(目前见到的最好用的)
    The 2019 Asia Nanchang First Round Online Programming Contest B Fire-Fighting Hero(阅读理解)
    关于RMQ问题的四种解法
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 K题 center
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
    The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
    ZOJ 3607 Lazier Salesgirl (枚举)
    ZOJ 3605 Find the Marble(dp)
  • 原文地址:https://www.cnblogs.com/zhang-da/p/12292498.html
Copyright © 2011-2022 走看看