selenium的三种等待方式
我们在做WEB自动化时,一般要等待页面元素加载完成后,才能执行操作,否则会报找不到元素的错误,这样就要求我们在有些场景下加等待时间
第一种: 强制等待
不管浏览器是否加载完成都强制等待5秒,相当于阻塞当前线程5秒。不建议过多使用,会严重影响脚本的性能。
from time import sleep sleep(5)
第二种: 隐式等待
基于浏览器的等待,相当于设置了浏览器的超时时间。
好处: 只需设置一次,全局都生效。如果超时时间内网页完成了全部加载,则立即进行下面的操作。比sleep()智能很多。
劣势: 隐式等待需要等到网页所有元素都加载完成才会执行下面的操作,如果我需要操作的元素提前加载好了,但是其他无关紧要的元素还没有加载完成,那么还是需要浪费时间去等待其他元素加载完成。
driver = webdriver.Chrome()
driver.implicitly_wait(2)
第三种: 显示等待
指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,那么便会抛出异常,只有当条件满足时才会执行后面的代码。
好处: 解决了隐式等待的不足之处。
缺点: 缺点是稍微复杂一些,需要有一些学习成本。
from selenium.webdriver.support.wait import WebDriverWait WebDriverWait(driver,timeout,poll_frequency,ignore_exceptions).until()/until_not()
参数解释:
driver 我们实例化的浏览器对象, 告诉脚本让谁去进行等待
timeout 最大的等待时间,超过之后抛出异常
poll_frequency 检查元素条件的频率,默认是0.5秒检查一次
Ignored_excepetions 等待期间忽略的异常
WebDriverWait这个类里面有两个方法 until 和 until_not. until表示让driver一直等到条件满足为止,until_not则相反
下面给大家介绍一下我们常见的预期等待条件,selenium很贴心,帮我们封装好了很多,我们导入对应的模块即可
expected_conditions 比较长我们通常给它取个别名EC
from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.baidu.com") WebDriverWait(driver,timeout,poll_frequency,ignore_exceptions).until(EC.title_is("百度一下,你就知道")) driver.find_element(By.ID, 'kw').send_keys("selenium") driver.find_element(By.ID, 'su').click() driver.maximize_window() driver.quit()
driver打开网址后,会一直等待到tile变为百度一下,你就知道然后马上开始下面的操作。
EC模块封装了很多常见的条件,这里也给大家介绍一下
最后我们比较一下三种等待方式执行相同任务所花的时间
import time from time import sleep from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions from selenium.webdriver.support.wait import WebDriverWait start_time = time.time() driver = webdriver.Chrome() driver.get("https://www.baidu.com") sleep(2) driver.find_element(By.ID, 'kw').send_keys("selenium") driver.find_element(By.ID, 'su').click() driver.maximize_window() driver.quit() end_time = time.time() print("sleep用时", end_time - start_time) # implicitly_wait(2) start_time = time.time() driver = webdriver.Chrome() driver.implicitly_wait(2) driver.get("https://www.baidu.com") driver.find_element(By.ID, 'kw').send_keys("selenium") driver.find_element(By.ID, 'su').click() driver.maximize_window() driver.quit() end_time = time.time() print("implicitly_wait用时", end_time - start_time) # WebdriverWait start_time = time.time() driver = webdriver.Chrome() driver.get("https://www.baidu.com") WebDriverWait(driver, 2).until(expected_conditions.element_to_be_clickable((By.ID, 'kw'))) driver.find_element(By.ID, 'kw').send_keys("selenium") driver.find_element(By.ID, 'su').click() driver.maximize_window() driver.quit() end_time = time.time() print("WebDriverWait用时", end_time - start_time)
输入内容为:
sleep用时 12.902432680130005
implicitly_wait用时 10.726516008377075
WebDriverWait用时 9.127316236495972
可以看到,在网速不理想的情况下还是有比较大的提升的。