1、目的背景

解决问题:下拉框定位不到、弹框定位不到…各种定位不到,其实大多数情况下就是两种问题:1 有frame,2 没有加等待。

原因:代码运行速度快,而浏览器加载渲染速度慢

解决办法:加等待,目前三种等待方式:强制等待、隐性等待、显性等待

2、强制等待 sleep(xx)

不管你浏览器是否加载完了,程序都得等待XX秒,XX秒一到,继续执行下面的代码,作为调试很有用,有时候也可以在代码里这样等待,不过不建议总用这种等待方式,太死板,严重影响程序执行速度。

3、隐性等待 implicitly_wait(xx)

隐形等待是设置了一个最长等待时间,如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间截止,然后执行下一步。

注意:隐性等待对整个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