欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

selenium的三种等待方式

程序员文章站 2022-05-12 20:04:32
...

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

selenium的三种等待方式

  • 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”信息。 

 

 

相关标签: selenium