web自动化的过程中,不能确定需要定位的元素何时完全加载完毕,如果实际页面等待时间过长导致某个dom元素还没出来,但是你的代码又直接定位了这个元素,那么就会抛出异常。为了避免这种情况,selenium提供了三种等待方式。
一、强制等待
语句为:time.sleep(x),强制等待Xs,等待X后再进行下一步操作
缺点:1.不能准确把握需要等待的时间;2.严重影响到自动化代码的运行
优点:方便调试
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
time.sleep(10) #强制等待10s,10s进行下一步操作
driver.refresh() #刷新当前页面
二、隐式等待
语句为:driver.implicitly_wait(X),最长等待X秒,若元素在X秒内出现则进行下一步操作,超过X秒页面下一步操作会报错
缺点:使用隐式等待,一般需要整个页面全部加载完成才可进行下一步操作
优点:对整个代码的driver都有效,只需导入一次
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")
driver.implicitly_wait(30) #最长等待30S,30S内加载完成则进行下一步操作
driver.find_element_by_id("kw").send_keys("Python")
driver.find_element_by_id("su").click()
三、显式等待
语句为:WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator)) ,显式等待指定某个条件,然后设置最长等待时间。如果在这个时间还没有找到元素,便抛出异常。其中20---表示最长等待时间;0.5---检查间隔时间,每隔0.5秒检查一次操作是否完成(不写此参数时,默认0.5s);EC.presence_of_element_located(locator)---判断目标元素是否已经成功加载;locator = (By.LINK_TEXT, 'A') A就是可以作为判断操作是否完成的标志
缺点:用法比较复杂,需多次调用
优点:1.等待判断准确,不会浪费多余的等待时间;2.可以提高代码执行效率
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait # WebDriverWait 库,负责循环等待
from selenium.webdriver.support import expected_conditions as EC # expected_conditions 类,负责条件出发
driver = webdriver.Chrome()
driver.get("http://www.xxxxx.com/loading")
try:
'''每隔10秒查找页面元素 id="myDynamicElement",直到出现则返回'''
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "myDynamicElement")))
finally:
driver.quit()
这三种等待方式,个人喜欢使用第二种,但如需提高代码效率建议第三种