selenium的三种等待方式

 如今大多数的 web 应用程序使用 AJAX 技术。当浏览器在加载页面时,页面内的元素可能并不是同时被 加 载 完 成 的 , 这 给 元 素 的 定 位 添 加 的 困 难 。 如 果 因 为 在 加 载 某 个 元 素 时 延 迟 而 造 成ElementNotVisibleException 的情况出现,那么就会降低的自动化脚本的稳定性。WebDriver 提供了两种类型的等待:显式等待和隐式等待。

  • sleep 休眠方法 

有时间我们希望脚本执行到某一位置时做固定时间的休眠,尤其是在脚本调试的过程中。那么可以使用 sleep()方法,需要说明的是 sleep()由 Python 的 time 模块提供。

#coding=utf-8
from selenium import webdriver
from time import sleep
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
sleep(2)
driver.find_element_by_id("kw").send_keys("webdriver")
driver.find_element_by_id("su").click()
sleep(3)
driver.quit()

当执行到 sleep()方法时会固定的休眠所设置的时长,然后再继续执行。sleep()方法默认参数以秒为单
位,如果设置时长小于 1 秒,可以用小数点表示,如:sleep(0.5) 表示休眠0.5秒。

  • 隐式等待

隐式等待是通过一定的时长等待页面所元素加载完成。哪果超出了设置的时长元素还没有被加载测抛NoSuchElementException异常。WebDriver 提供了 implicitly_wait()方法来实现隐式等待,默认设置为 0。它的用法相对来说要简单的多。driver.implicitly_wait(10) # 隐性等待,最长等10秒

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw22")
input_.send_keys('selenium')
driver.quit()

implicitly_wait()默认参数的单位为秒,本例中设置等待时长为 10 秒,首先这 10 秒并非一个固定的等
待时间,它并不影响脚本的执行速度。其次,它并不真对页面上的某一元素进行等待,当脚本执行到某个
元素定位时,如果元素可定位那么继续执行,如果元素定位不到,那么它将以轮询的方式不断的判断元素
是否被定位到,假设在第 6 秒钟定位到元素则继续执行。直接超出设置时长(10 秒)还没定位到元素则抛
出异常。
在上面的例子中,显然百度输入框的定位 id=kw22 是有误的,那么在超出 10 秒后将抛出异常。 

  • 显式等待 

显式等待使 WebdDriver 等待某个条件成立时继续执行,否则在达到最大时长时抛弃超时异常(TimeoutException)。

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
element = WebDriverWait(driver,5,0.5).until(
EC.presence_of_element_located((By.ID,"kw"))
)
element.send_keys('selenium')
driver.quit()

WebDriverWait()
它是由 webdirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存在,如果超过设置时间检测不到则抛出异常。具体格式如下:

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

WebDriverWait(driver, 5,0.5).until( EC.presence_of_element_located((By.ID, "kw"))) 

driver - WebDriver 的驱动程序(Ie, Firefox,Chrome 等)
timeout - 最长超时时间,默认以秒为单位

poll_frequency - 休眠时间的间隔(步长)时间,默认为 0.5 秒
ignored_exceptions - 超时后的异常信息,默认情况下抛 NoSuchElementException 异常。
until(method, message=’ ’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 Ture。
until_not(method, message=’ ’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False。

Expected Conditions
在本例中,我们在使用 expected_conditions 类时对其时行了重命名,通过 as 关键字对其重命名为 EC,
并调用 presence_of_element_located()判断元素是否存在。Expected Conditions类提供预期条件判断方法请另行查阅。除了 expected_conditions 所提供的预期方法,通过 is_displayed()方法来判断元素是否可见,查看以下两个例子。

#coding=utf-8
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
input_ = driver.find_element_by_id("kw")
element = WebDriverWait(driver,5,0.5).until(
lambda driver : input_.is_displayed()
)
input_.send_keys('selenium')
driver.quit()

lambad 为 Python 创建匿名函数的关键字。关于 Python 匿名函数的使用这里不再进行讲解,请参考Python 相关教程。
定义 input_为百度输入框,通过 is_displayed()判断其是否可见。 

from selenium import webdriver
from time import sleep,ctime

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")

print(ctime())
for i in range(10):
    try:
        el=driver.find_element_by_id("kw22")
        if el.is_displayed(): 
                        break
        except:pass
        sleep(1)
    else:
        print("time out")
    driver.close()
    print(ctime())
       

通过for循环10次,每次循环判断元素的is_dispalyed()状态是否为True:如果为True,则break跳出循环;否则sleep(1)后继续循环判断,直到10次循环结束后,打印“time out”信息。 

猜你喜欢

转载自blog.csdn.net/qq_42492845/article/details/81173421