显示等待、隐式等待、强制等待
强制等待sleep()
import time
sleep(2) #强制等待2秒
显示等待WebDriverWait()
显式等待是 WebDriver 等待某个条件成立则继续执行,否则在达到最大时长时抛出超
时异常(TimeoutException)。
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("https://www.baidu.com")
element = WebDriverWait(driver, 5, 0.5).until(
EC.visibility of element located((By.ID, "kw"))
)
element.send_keys('selenium')
ddriver.quit()
WebDriverWait 类是 WebDriver 提供的等待方法。在设置时间内,默认每隔一段时间检
测一次当前页面元素是否存在,如果超过设置时间仍检测不到,则抛出异常。具体格式如下。
WebDriverWait(driver, timeout, poll_frequency = 0.5, ignored_execeptions=None)
-
driver:浏览器驱动。
-
timeout:最长超时时间,默认以秒为单位。
-
poll_frequency:检测的间隔(步长)时间,默认为 0.5s。
-
ignored_exceptions:超时后的异常信息,默认情况下抛出 NoSuchElementException异常。
WebDriverWait()一般与 until()或 until_not()方法配合使用,下面是 until()和 until_not()方法的说明。
until(method, message=″)
调用该方法提供的驱动程序作为一个参数,直到返回值为 True。
until_not(method, message=″)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False。
在本例中,通过 as 关键字将 expected_conditions 重命名为 EC,并调用 presence_of_element_located()方法判断元素是否存在。
expected_conditions 类提供的预期条件判断方法如下表所示。
除 expected_conditions 类提供的丰富的预期条件判断方法外,还可以利用前面学过的is_displayed()方法自己实现元素显示等待。
from time import sleep
from selenium import webdriver
driver = webdirver.Chrome()
driver.get("https://www.baidu.com")
print(ctime())
for i in range(10):
try:
el = driver.find_element_by_id("kw22")
if el.is_displayed():
break
except:
pass
sleep(1)
else:
print("timeout")
print(citme())
driver.quit()
相对来说,这种方式更容易理解。首先 for 循环 10 次,然后通过 is_displayed()方法循环判断元素是否可见。如果为 True,则说明元素可见,执行 break 跳出循环;否则执行 sleep()休眠 1s 后继续循环判断。10 次循环结束后,如果没有执行 break,则执行 for 循环对应的else 语句,打印“time out”信息。
这里故意将 id 定位设置为“kw22”,定位失败,执行结果如下。
隐式等待
WebDriver 提供的 implicitly_wait()方法可用来实现隐式等待,用法相对来说要简单得多。
from time import ctime
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
driver = webdriver.Chrome()
#设置隐式等待为10s
driver.implicitly_wait(10)
driver.get("http:www.baidu.com")
try:
print(ctime())
driver.find_element_by_id("kw22").send_keys("selenium")
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
driver.quit()
("selenium")
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
driver.quit()
implicitly_wait()的参数是时间,单位为秒,本例中设置的等待时间为 10s。首先,这10s 并非一个固定的等待时间,它并不影响脚本的执行速度。其次,它会等待页面上的所有元素。当脚本执行到某个元素定位时,如果元素存在,则继续执行;如果定位不到元素,则它将以轮询的方式不断地判断元素是否存在。假设在第 6s 定位到了元素,则继续执行,若直到超出设置时间(10s)还没有定位到元素,则抛出异常。