一、强制等待
import time
time.sleep(10) #无论发生什么事情,强制等待十秒
......
二、隐性等待
implicitly_wait(秒):设置最长等待时间,在这个时间内加载完成,则执行下一步。(比如第2秒就找到了元素,则不再等待,直接执行下一步)
注意:因为是driver的方法,因此在整个driver的会话周期内(打开浏览器到关闭浏览器的周期内),设置一次即可,全局都可用。
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(10) #后续的find_element方法都会有上面的等待
#如果第2秒就找到了元素,则不再等待,会执行下一步的click方法
driver.find_element_by_class_name("consignName").click()
三、显性等待
显性等待:即明确等到某个条件满足之后,再去执行下一步操作。
在python程序中的体现为:程序每隔xxx秒看一眼,如果条件成立了,则执行下一步。否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException。
相关类介绍:
1、WebDriverWait类:显性等待类。
使用方法:
WebDriverWait(driver, 等待时长, 轮循周期).until()/until_not()
2、expected_conditions模块:提供了一系列期望发生的条件。
例如:
presense_of_element_located:元素存在
visibility_of_element_located:元素可见
element_to_be_clickable:元素可点击
......还有很多其他的条件
在具体写代码时的用法:
WebDriverWait(driver,timeout,poll_frequency).until(EC.visibility_of_element_located(locator))
参数介绍:
①driver:webdriver实例,不然怎么知道是哪个浏览器执行这个操作
②timeout:你想等待条件成立的时间
③poll_frequency:轮循周期,就是前面说的每隔多久去检查条件是否成立
④locator:元素定位
具体使用方法示例:
1 from selenium.webdriver.support.wait import WebDriverWait
2 from selenium.webdriver.support import expected_conditions as EC
3 from selenium.webdriver.common.by import By
4
5 WebDriverWait(driver,30,1).until(EC.visibility_of_element_located((By.ID,"login_btn")))
selenium官网提供的条件略览:
| 方法用途 | 代码示例 (元素:login=(By.ID,"login_btn") |
| 检查当前窗口的title是否等于给定的值。是返回True,不是返回False。 (使用时要注意当前的window) | EC.title_is("登录页面") |
| 检查当前窗口的title是否包含给定的值。是返回True,不是返回False。 | EC.title_contains("登录页面") |
| 检查给定的元素是否存在于页面DOM树内。并不需要该可见。 存在返回返回True,不存在返回False。 | EC.presence_of_element_located(login) |
| 检查当前窗口的url是否包含给定的值。包含返回True,不包含返回False。 | EC.url_contains("register") |
| 作用同url_contains,只是可以是正则表达式,返回True或False | EC.url_contains("\/.*") |
| 检查当前窗口的url是否等于给定的值。等于返回True,否则False。 | EC.url_to_be("xxx") |
| 检查当前窗口的url是否不等于给定的值。不等于返回True,否则False。 | |
| 检查给定的元素是否存在于页面DOM树内并且可见。可见的意思元素显示在页面上,并且宽、高都大于0。 满足上述条件则返回元素。 | 参数:locator EC.visibility_of_element_located(login) |
| 和visibility_of_element_located一样。只是传入的参数变成了元素。 | ele=driver.find_element(*login) EC.visibility_of(ele) |
| 检查是否可以切换到给定的frame。如果可以则切换到frame并返回True,否则False | 参数:locator |
| 检查某个元素是否可见并且可点击。满足条件则返回元素,否则False | 参数:locator |
| 检查新窗口是否打开(通过比对传入的窗口队列数量和当前窗口队列数量。)如果当前窗口队列数量>传入的窗口队列数量,则返回True,否则False | 参数:current_handles current_handle=driver.window_handles |
| 检查窗口数量是否等于给定的值。(通过比对当前窗口队列数量是否等于给定的值)等于返回True,否则False | 参数:number |
| 检查alert是否出现。如果出现则切换到alert并且返回该alert,否则返回False。 | 无参数 |
| 检查至少有一个元素出现。返回元素集合。 | 参数:locator |
啰嗦一句,可能刚开始无法区分presence_of_element_located和visibility_of_element_located。这样理解:
1、presense是指出现,出现在DOM中。但是出现在DOM中该元素也可能看不见它对吧,比如代码中可以通过CSS(display:none)或JS把它隐藏起来了。
2、visibility是指可以看见。既然可以看见,就肯定包含了presense的情况。但是此处的visibility不仅是指我们在浏览器可视区域内可见,拖动浏览器的滚动条可见也算哦。
3、实际情况下,我都是用的visibility_of_element_located。不然元素都隐藏起来了,你怎么操作元素呢?若元素presence_of_element_located为True,visibility_of_element_located为False,这时你仍固执的对元素执行click、send_keys操作,就会报ElementNotInteractableException(有道翻译 interactable:可交互的):
4、上述3点,我都是实际测试过的。