但是,由于ajax和各种JS代码的异步加载问题,当一个页面被加载到浏览器时,
该页面内的元素可以在不同的时间点被加载,这就使得元素的定位变得十分困难,
当元素不再页面中时,使用会抛出ElementNotVisibleException异常,为了解决这个问题,
selenium提供了两种等待页面加载的方式,显示等待和隐式等待,
让我们可以等待元素加载完成后在进行操作。
隐性等待:设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,
否则一直等到时间截止,然后执行下一步。
一般写法:WebDriverWait(driver, timeout, poll_frequency, igonred_exceptions).until(method, message)
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "myDynamicElement"))
Driver:传入WebDriver实例。
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until中的方法的间隔时间,默认是0.5秒
ignored_exceptions: 忽略的异常,如果在调用until的过程中抛出这个元组中的异常,则不中断代码,继续等待.
Method:可执行方法
Message: 超时时返回的信息
例子
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.Chrome() driver.get("http://somedomain/url_that_delays_loading") try: element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "myDynamicElement")) ) finally: driver.quit()
在这个例子中,我们在查找一个元素的时候,不再使用find_element_by_*
这样的方式来查找元素,
而是使用了WebDriverWait
。
try代码块中的代码的意思是:在抛出元素不存在异常之前,最多等待10秒。在这10秒中,
WebDriverWait
会默认每500ms运行一次until之中的内容,
而until中的EC.presence_of_element_located
则是检查元素是否已经被加载,检查的元素则通过By.
ID
这样的方式来进行查找。
就是说,在10秒内,默认每0.5秒检查一次元素是否存在,存在则将元素赋值给element这个变量。
如果超过10秒这个元素仍不存在,则抛出超时异常。
expected_conditions是selenium的一个模块,其中包含一系列可用于判断的条件,配合该类的方法,
就能够根据条件而进行灵活地等待了
from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) # 等待直到元素可以被点击 element = wait.until(EC.element_to_be_clickable((By.ID, 'someid')))
隐式等待指的是,在webdriver
中进行find_element
这一类查找操作时,如果找不到元素,则会默认的轮询等待一段时间。
这个值默认是0,可以通过以下方式进行设置:
from selenium import webdriver driver = webdriver.Chrome() driver.implicitly_wait(10) # 单位是秒 driver.get("http://somedomain/url_that_delays_loading") myDynamicElement = driver.find_element_by_id("myDynamicElement")