selenium中元素等待有三种方式,分别是强制等待,隐式等待和显示等待
简单粗暴好用,不管怎样就给我睡几秒,调试经常用到,不过真正跑生产时影响速度,看情况使用
import time
time.sleep(3)
设置一个全局隐性等待时间,如果在等待时间内找到了就执行下一步,未找到则报错。隐式等待只需设置一次后,对所有元素生效。假如我们需要的某个元素已经出现了,此时仍然需要等其他元素加载完毕,才能执行下一步,这是它的缺点,这种情况就要用到显示等待了。
每隔一段时间看一下,条件成立执行下一步,到达设置的最长时间还未满足,则抛出超时异常。 显示等待需要用到webdriverwait 类,配合该类的until()和until_not()方法根据条件判断是否执行下一步,结合expected_conditions使用
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://www.jd.com")
driver.implicitly_wait(3) # 设置隐式等待时间
driver.quit()
每隔一段时间看一下,条件成立执行下一步,到达设置的最长时间还未满足,则抛出超时异常。 显示等待需要用到webdriverwait 类,配合该类的until()和until_not()方法根据条件判断是否执行下一步,结合expected_conditions使用
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.jd.com")
WebDriverWait(driver, 10,2).until(EC.presence_of_element_located((By.id, 'key')))
#每隔2s判断元素是否出现,2可以不设置,默认为0.5s轮询一次,最长10s,超时未出现则报错
until_not(self, method, message: str = "") 函数,until_not效果与until相反,返回false时判断成功,返回true时判断失败
expected_conditions模块提供了17种判断方法
隐式等待和显示等待都设置了时,以时间长的为准
三大等待方式是基于网页加载完成后,元素未加载完成的情况下才能执行的方式。有一种情况是,网页还没加载完成,想要的元素都已经出现了,页面也可以操作,这个时候你去设置这些等待方式都是不起作用的,因为它要先等网页加载完成。比如下面这个网站,打开的时候这个输入框元素和整个页面早就加载出来了,已经可以操作,但由于某个脚本还在加载,脚本真正要去输入需要等这个网页加载完成才能获取得到,而这个网页加载完成需要20多秒
from selenium import webdriver
import time
input = '//*[@id="RA-root"]/div/div[1]/div[1]/div[2]/span/span/span[1]/input1'
driver.get("https://www.geeksforgeeks.org/")
driver.find_element(By.XPATH, input).send_keys("python")
#input_ele = WebDriverWait(driver,10,5).until(EC.presence_of_element_located((By.XPATH, input )))
#driver.implicitly_wait(10)
#time.sleep(10)
#这个时候不管设置哪些等待方式都没用,页面加载完成需要二十多秒,才会执行下一步
针对这种情况,我们可以通过set_page_load_timeout()设置页面加载时间后手动终止页面加载,继续执行下一步
from selenium import webdriver
input = '//*[@id="RA-root"]/div/div[1]/div[1]/div[2]/span/span/span[1]/input'
try:
driver.set_page_load_timeout(10) #设置页面加载时间,超时没完成则捕获异常
#driver.set_script_timeout(10)
driver.get("https://www.geeksforgeeks.org/")
except Exception as e:
print(e)
#driver.execute_script('window.stop()') #手动停止页面加载
print("超时,直接进入下一步")
driver.find_element(By.XPATH, input).send_keys("python")
注意要把异常捕获,不捕获程序会直接抛出超时异常而终止程序。
Web页面属性document.readyState描述当前页面的加载状态,该属性有三个值:loading(正在加载)、interactive(可交互)、complete(完成)。
默认情况下,在document.readyState为COMPLETE之前,WebDriver都将延迟driver.get()的响应或 driver.navigate().to()的调用。
在单页应用程序中(例如Angular、React、Ember),一旦动态内容加载完毕(即pageLoadStrategy状态为COMPLETE) 则点击链接或在页面内执行某些操作的行为将不会向服务器发出新请求, 因为内容在客户端动态加载, 无需刷新页面。单页应用程序可以动态加载许多视图, 而无需任何服务器请求,因此页面加载策略将始终显示为COMPLETE的状态, 直到我们执行新的 driver.get()或driver.navigate().to()为止。
WebDriver支持的三种页面加载策略
pageLoadStrategy有三种取值:
normal:等待整个页面的加载,Selenium WebDriver保持等待,直到返回load事件。默认情况下,如果未设置页面加载策略,则设置 normal为初始策略。
eager:Selenium WebDriver保持等待,直到完全加载并解析了HTML文档,该策略无关样式表、图片和subframes的加载。设置为 eager时,Selenium WebDriver保持等待, 直至返回DOMContentLoaded事件。
none:Selenium WebDriver仅等待至初始页面下载完成。
默认情况下,当Selenium WebDriver加载页面时,遵循normal的页面加载策略。始终建议您在页面加载缓慢时,停止下载其他资源 (例如图片、css、 js) 。
页面加载策略设置方法
from selenium import webdriver
options = Options()
options.page_load_strategy = 'normal' # normal eager none 默认normal
driver = webdriver.Chrome(options=options)
driver.get("https://www.baidu.com")
print(driver.capabilities)