selenium(5)-解读强制等待,隐式等待,显式等待的区别
背景
为什么要设置元素等待
- 因为,目前大多数Web应用程序都是使用Ajax和Javascript开发的;每次加载一个网页,就会加载各种HTML标签、JS文件
- 但是,加载肯定有加载顺序,大型网站很难说一秒内就把所有东西加载出来,不仅如此,加载速度也受网络波动影响
- 因此,当我们要在网页中做元素定位的时候,有可能我们打开了网页但元素未加载出来,这个时候就定位不到元素,就会报错
- 所以,我们需要设置元素等待,意思就是:等待指定元素已被加载出来之后,我们才去定位该元素,就不会出现定位失败的现
强制等待
如果我们不设置元素等待,怎么避免因元素未加载出来定位失败的情况出现
- 使用sleep(),也叫强制等待
- 缺点就是如果指定的时间过长,就算元素已经加载出来了,还要继续等待,这样会浪费很多时间,脚本运行的时间会很长
1 from time import sleep 2 from selenium import webdriver 3 4 driver = webdriver.Chrome("xxxx/chromedriver.exe") 5 20) 6 7 # 访问网址 8 driver.get("http://www.baidu.com") 9 10 # ===强制等待3秒才执行下一步=== 11 sleep(3) 12 13 # 找到搜索框 14 inputElement = driver.find_element_by_id("kw")
隐式等待
webdriver提供了两种类型的等待分别是隐式等待,显式等待
什么是隐式等待
- 如果某些元素不是立即可用的,隐式等待是告诉WebDriver去等待一定的时间后去查找元素
- 默认等待时间是0秒,隐式等待对整个WebDriver的周期都起作用,所以只要设置一次即可
如何体现隐式等待
如果在规定时间内,整个网页都加载完成,则执行下一步,否则会抛出异常
隐式等待的弊端
可以把隐式等待当做全局变量,它影响整个页面,所以程序需要等待整个页面加载完成(就是浏览器标签栏那个小圈不再转)时,才会执行下一步【页面加载完成,才能执行下一步】
但可能页面加载未完成的时候,需要定位的元素已经加载完成了,但受限于某些JS文件、图片加载特别慢,我们不能执行下一步,必须得等到网页所有东西都加载完了才能下一步【增加不必要的加载时间】
隐式等待的代码举例
很简单,就调用一个方法即可,毕竟是作用于WebDriver的
1 from selenium import webdriver 2 3 # 加载驱动 4 driver = webdriver.Chrome("xxxx/chromedriver.exe") 5 6 # ===隐性等待20s=== 7 driver.implicitly_wait(20) 8 9 # 访问网址 10 driver.get("http://www.baidu.com") 11 12 # 找到搜索框 13 inputElement = driver.find_element_by_id("kw")
显式等待(推荐使用)
什么是显式等待
- 需要定位某个元素的时候,但元素可能不可见,这个时候针对这个元素就可以使用显式等待了
- 显式等待和隐式等待最大的不同就是:你可以它看成是局部变量,作用于指定元素
显式等待的好处
相比隐式等待,显式等待只对指定元素生效,不再是在整个WebDriver生命周期内生效【仅对元素生效】
可以根据需要定位的元素来设置显式等待,无需等待页面完全加载,节省大量因加载无关紧要文件而浪费掉的时间【针对元素设置,无需等待页面加载完成,节省加载时间】
显式等待的代码举例
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 """ 5 __title__ = 6 __Time__ = 2020/3/25 17:52 7 __Author__ = xinhua 8 __Blog__ = https://www.cnblogs.com/xinhua19/ 9 """ 10 from time import sleep 11 12 from selenium import webdriver 13 14 # 加载驱动 15 from selenium.webdriver.common.by import By 16 from selenium.webdriver.support.wait import WebDriverWait 17 from selenium.webdriver.support import expected_conditions as EC 18 19 driver = webdriver.Chrome("xxxx/chromedriver.exe") 20 21 # 访问网址 22 driver.get("http://www.baidu.com") 23 24 # ===显式等待===,# 设置元素等待实例,最多等12秒,一段时间检查条件是否成立 25 class BasePage: 26 scheme = localReadConfig.get_http("scheme") 27 base_url = scheme + r"://" + localReadConfig.get_http("baseurl") 28 29 def __init__(self, driver, url=None): 30 self.url = url 31 self.driver = driver 32 self.timeout = 12 33 self.wait = WebDriverWait(self.driver, self.timeout) 34 35 self.url = self.base_url 36 if url: 37 self.url = self.base_url + url 38 39 def wait_for_element_visible(self, locator): 40 self.wait.until(EC.visibility_of_element_located(locator))
1 from time import sleep 2 3 from selenium import webdriver 4 5 # 加载驱动 6 from selenium.webdriver.common.by import By 7 from selenium.webdriver.support.wait import WebDriverWait 8 from selenium.webdriver.support import expected_conditions as EC 9 10 driver = webdriver.Chrome("../resources/chromedriver.exe") 11 12 # 访问网址 13 driver.get("http://www.baidu.com") 14 15 # ===显式等待=== 16 17 # 设置元素等待实例,最多等10秒,每0.5秒查看条件是否成立 18 element = WebDriverWait(driver, 10, 0.5).until( 19 # 条件:直到元素加载完成 20 EC.presence_of_element_located((By.ID, "kw")) 21 )