1、目的背景
解决问题:下拉框定位不到、弹框定位不到…各种定位不到,其实大多数情况下就是两种问题:1 有frame,2 没有加等待。
原因:代码运行速度快,而浏览器加载渲染速度慢
解决办法:加等待,目前三种等待方式:强制等待、隐式等待、显示等待
2、强制等待 sleep(xx)
不管你浏览器是否加载完了,程序都得等待XX秒,XX秒一到,继续执行下面的代码,作为调试很有用,有时候也可以在代码里这样等待,不过不建议总用这种等待方式,太死板,严重影响程序执行速度。
3、隐式等待 implicitly_wait(xx):在指定时间内,轮询(间隔0.5)查看是否复合要求(全局的)
隐形等待是设置了一个最长等待时间,轮询查找,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。
注意:隐性等待对整个driver的周期都起作用,所以只要设置一次即可。
弊端:那就是程序会一直等待整个页面加载完成,也就是一般情况下你看到浏览器标签栏那个小圈不再转,才会执行下一步,但有时候页面想要的元素早就在加载完成了,但是因为个别js之类的东西特别慢,我仍得等到页面全部完成才能执行下一步
4、显性等待 WebDriverWait:在指定时间内,轮询查看是否复合要求(指定的)
注意:需要指定一个具体的元素
程序每隔xx秒看一眼,如果条件成立了,则执行下一步,否则继续等待,直到超过设置的最长时间,然后抛出TimeoutException
隐性等待和显性等待可以同时用,但要注意:等待的最长时间取两者之中的大者
# -*- 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 By driver = 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)) # 每隔 0.5s 执行一次,直到 20s print driver.find_element_by_link_text('CSDN').get_attribute('href') finally: driver.close()
WebDriverWait(driver, 超时时长, 调用频率, 忽略异常).until(可执行方法, 超时时返回的信息)
selenium.webdriver.support.wait.WebDriverWait(类) __init__ driver: 传入WebDriver实例,即我们上例中的driver timeout: 超时时间,等待的最长时间(同时要考虑隐性等待时间) poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒 ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断代码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。 until method: 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是False message: 如果超时,抛出TimeoutException,将message传入异常 until_not 与until相反,until是当某元素出现或什么条件成立则继续执行,until_not是当某元素消失或什么条件不成立则继续执行,参数也相同,不再赘述。 method message