现在的大多数的Web应用程序是使用Ajax或一些前端框架技术来完成加载页面,这样程序便不能确定某个元素何时才能完全加载出来。因不能确定元素被加载到浏览器的时间,这使得定位元素变得困难。
如果程序定位某个元素时,实际页面中这个元素还未完全加载进来或元素不再页面之中,会抛出 ElementNotVisibleException 异常。为了解决这个问题,我们可以使用 selenium 提供的 waits 更好的解决这个问题。waits提供了一些操作之间的时间间隔,主要是定位元素或针对该元素的任何其他操作。
Selenium Webdriver 提供两种类型的 waits - 隐式等待和显式等待。显式等待会让 WebDriver 等待满足一定的条件以后再进一步的执行。 而隐式等待让 Webdriver 等待一定的时间后再才是查找某元素。
显式等待:
显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码。简单的说就是在指定时间内,一直等待某个条件成立,条件成立后立即执行定位元素的操作;如果超过这个时间条件仍然没有成立,则会抛出异常!显式等待需要使用 selenium.webdriver.support.excepted_conditions 期望条件和 selenium.webdriver.support.ui.WebDriverWait 类来配合完成。
隐式等待:
隐式等待实际是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间结束,然后执行下一步。如果某些元素不是立即可用的,隐式等待是告诉 WebDriver 去等待一定的时间后去查找元素。默认等待时间是0秒,一旦设置该值,隐式等待是设置该 WebDriver 的实例的生命周期。这样的隐式等待会有个坑,有些页面的JS是放在body的最后进行加载,实际这是页面上的元素都已经加载完毕,我们却还在等待全部页面加载结束。
需要特别说明的是:隐性等待对整个 driver 的周期都起作用,所以只要设置一次即可(在最开始设置一次就可以了),切不要当作固定等待使用。
熟悉了什么是显式等待和隐式等待,下面就让我们来看看怎么使用这两种等待吧。
显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码。
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
driver = webdriver.Chrome()
driver.get("url")
locator = (By.ID, "你的标签ID")
# 显式等待:条件成立,立即执行;超过指定时间则报错
WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located(locator))
driver.find_element_by_id("你的标签ID").click()
# 或
element = WebDriverWait(driver, 10).until(expected_conditions.presence_of_element_located((By.ID, "你的标签ID")))
element.click()
注意:传入的定位条件必须是元组形式。
代码说明:
WebDriverWait(driver, 10):设置了一个10秒上限的等待时间。在指定时间内,一直等待某个条件成立,条件成立后立即执行定位元素的操作;如果超过这个时间条件仍然没有成立,则会抛出 TimeoutException 异常!
expected_conditions:后面是自动化的Web浏览器中一些常用的预期条件。请参考XXXXXXXXXXXXXXXXX
WebDriverWait参数:
这个模块中,一共只有两种方法 until 与 until_not:
until 与 until_not 参数如下:
如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素。默认等待时间是0秒,一旦设置该值,隐式等待是设置该WebDriver的实例的生命周期。
from selenium import webdriver
driver = webdriver.Chrome()
# 隐式等待:最长等待10秒钟往下执行
driver.implicitly_wait(10)
driver.get("url")
# 执行定位元素操作
element = driver.find_element_by_id("标签ID")
注意:隐式等待和显示等待都存在时,超时时间取二者中较大的。
—————————
如有不足请留言指正
相互学习,共同进步