在Selenium Webdriver中等待的方式简单可以概括为三种:
1、导入time包,调用time.sleep()的方法传入时间,这种方式也叫强制等待,固定死等一个时间
2、隐式等待,直接调用implicitly_wait()方法,传入等待时间,比如implicitly_wait(10),就代表最长等待10秒
表示在自动化实施过程中,为查找页面元素或者执行命令设置一个最长等待时间,如果在规定时间内也没元素被找到或命令被执行完成,则执行下一步,否则继续等待直到设置的最长等待时间截止
3、显式等待,导入WebDriverWait和expected_conditions包,调用until()者until_not()方法
通过selenium.webdriver.suppert.ui模块提供的WebDriverWait类,再结合该类的until()和until_not()的方法,并自定义好等待时间,根据判断条件进行灵活等待。显式等待比隐式等待更节约执行时间,因此更推荐使用显式等待方式判断页面元素是否存在
-- coding: utf-8 --
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import Bydriver = webdriver.Firefox()
driver.implicitly_wait(10) # 隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者
driver.get(‘https://huilansame.github.io’)
locator = (By.LINK_TEXT, ‘CSDN’)try:
WebDriverWait(driver, 20, 0.5).until(EC.presence_of_element_located(locator))
print driver.find_element_by_link_text(‘CSDN’).get_attribute(‘href’)
finally:
driver.close()
需要特别说明的是:隐性等待对整个driver的周期都起作用,所以只要设置一次即可,我曾看到有人把隐性等待当成了sleep在用,走哪儿都来一下…
隐形等待
是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。注意这里有一个弊端,那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步,我想等我要的元素出来之后就下一步怎么办?有办法,这就要看selenium提供的另一种等待方式——显性等待wait了
显性等待
WebDriverWait,配合该类的until()和until_not()方法,就能够根据判断条件而进行灵活地等待了。它主要的意思就是:程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException
上例中,我们设置了隐性等待和显性等待,在其他操作中,隐性等待起决定性作用,在WebDriverWait…中显性等待起主要作用,但要注意的是:最长的等待时间取决于两者之间的大者,此例中为20,
如果隐性等待时间 > 显性等待时间,则该句代码的最长等待时间等于隐性等待时间。
wait模块的WebDriverWait类是显性等待类,先看下它有哪些参数与方法:
selenium.webdriver.support.wait.WebDriverWait(类)
element=WebDriverWait(driver,5,0.5),until(EC.presence_of_element_located((By.ID,‘su’)))
element=WebDriverWait(driver,5,0.5).until(EC.presence_of_element_located(locator))
init
driver: 传入WebDriver实例,即我们上例中的driver
timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间)
poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException
概念:
显示等待是针对某一个元素进行相关等待判定
隐式等待不针对某一个元素进行等待,是全局元素等待
相关模块(类):
WebDriverWait #显示等待,对元素比用
expectd_conditions #预期条件类(里面包含方法可以调用,用于显示等待)
NoSuchElementException #用于隐式等待跑出异常
By #用于元素定位
1、显示等待:
导入相关模块:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC #定义了变量EC表示expected_conditions
from selenium.webdriver.common.by import By
from selenium.common.exceptions import NoSuchElementException
显示等待如下:
driver=webdriver.Firefox()
driver.get("https://www.baidu.com")
driver.find_element_by_css_selector('#kw').send_keys('python')
time.sleep(2)
element=WebDriverWait(driver,5,0.5),until(EC.presence_of_element_located((By.ID,'su')))
解释:WebDriverWait(driver,5,0.5)5表示等待的最大时长秒单位,0.5位间隔秒
EC.presence_of_element_located((By.ID,'su'))方法本身调用时有括号,所以调用时会有双括号填入参数
2、隐式等待:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import time
driver=webdriver.Firefox()
driver.get("https://www.baidu.com")
driver.implicitly_wait(5) #隐式等待,设置等待时长5秒
try:
print(time.ctime())
driver.find_element_by_css_selector('#kw').send_keys('python')
driver.find_element_by_css_selector('#su').click()
except NoSuchElementException as msg:
print(msg)
finally:
print(time.ctime())