强制等待
属于一种固定等待,一般用于调试阶段或者演示阶段
import time
time.sleep(2) # 强制等待的语法
隐式等待
特点:
01 隐式等待只需要设置一次,即全局生效[元素定位],但是针对一些应用场景也存在不生效的情况[例如url的渐变,重定向,标题的改变等] 02 如果元素可以定位,则继续执行接下来的操作,如果超过最大等待时间元素仍定位不到,则会报异常处理
缺陷
如果你只需要等待某个元素加载完成进行操作,但是该等待方式需要等待界面上的所有元素全部加载完毕,才会执行元素操作,从而存在因为加载整个页面元素而浪费时间问题
from selenium import webdriver
driver = webdriver.Chrome()
driver.implicitly_wait(5) # 隐式等待的语法
'''
隐式等待源码:
def implicitly_wait(self, time_to_wait) -> None: # 即time_to_wait表示最大的等待时间,单位为秒
"""
Sets a sticky timeout to implicitly wait for an element to be found,
or a command to complete. This method only needs to be called one
time per session. To set the timeout for calls to
execute_async_script, see set_script_timeout.
:Args:
- time_to_wait: Amount of time to wait (in seconds)【表示最大的等待时间,单位为秒】
:Usage:
::
driver.implicitly_wait(30)
"""
self.execute(Command.SET_TIMEOUTS, {
'implicit': int(float(time_to_wait) * 1000)})
'''
显式等待
相对于隐式等待,显式等待是针对于某个具体的元素或者某种行为进行的特征判断,一旦具备了该特征,就会执行接下来的操作 另外,隐式等待和显式等待根据官方介绍不能进行混用,会产生意想不到的结果
# 显式等待需要导入的包
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from selenium import webdriver
driver = webdriver.Chrome()
wait = WebDriverWait(driver=driver,timeout=8) # 主要是设置最大的超时时间
ele_locator = ['id', 'usename']
wait.until(ec.presence_of_element_located(ele_locator))
'''
01 WebDriverWait源码:
POLL_FREQUENCY: float = 0.5 # How long to sleep in between calls to the method 【即轮询时间。默认时间为0.5秒】
IGNORED_EXCEPTIONS: typing.Tuple[typing.Type[Exception]] = (NoSuchElementException,) # default to be ignored.
class WebDriverWait:
def __init__(self, driver, timeout: float, poll_frequency: float = POLL_FREQUENCY, ignored_exceptions: typing.Optional[WaitExcTypes] = None):
"""Constructor, takes a WebDriver instance and timeout in seconds.
:Args:
- driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote) 【浏览器实例】
- timeout - Number of seconds before timing out 【最大等待/超时时间】
- poll_frequency - sleep interval between calls 【轮询时间】
By default, it is 0.5 second.【默认为0.5秒】
- ignored_exceptions - iterable structure of exception classes ignored during calls. 【超时后的异常信息】
By default, it contains NoSuchElementException only.
Example::
from selenium.webdriver.support.wait import WebDriverWait \n
element = WebDriverWait(driver, 10).until(lambda x: x.find_element(By.ID, "someId")) \n
is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).\\ \n
until_not(lambda x: x.find_element(By.ID, "someId").is_displayed())
"""
self._driver = driver
self._timeout = float(timeout)
self._poll = poll_frequency
# avoid the divide by zero
if self._poll == 0:
self._poll = POLL_FREQUENCY
exceptions = list(IGNORED_EXCEPTIONS)
if ignored_exceptions:
try:
exceptions.extend(iter(ignored_exceptions))
except TypeError: # ignored_exceptions is not iterable
exceptions.append(ignored_exceptions)
self._ignored_exceptions = tuple(exceptions)
'''
'''
02 WebDriverWait实例对象的方法:
wait.until() 【直到满足。。。条件】
wait.until_not() 【直到不满足。。。条件】
'''
'''
03 expected_conditions下的各类方法
例如:presence_of_element_located(ele_locator)等
'''
expected_conditions下的各类方法
01 title_is
判断是否和预期的浏览器标题相等
'''
源码:
def title_is(title):
"""An expectation for checking the title of a page.
title is the expected title, which must be an exact match
returns True if the title matches, false otherwise."""
def _predicate(driver):
return driver.title == title
return _predicate
作用:
判断是否和预期的浏览器标题相等
传入参数:
title [传入预期的浏览器的标题名称]
返回值:
布尔值【True/False】
'''
02 title_contains
判断预期的浏览器标题是否存在于当前实际的浏览器标题中
'''
源码:
def title_contains(title):
""" An expectation for checking that the title contains a case-sensitive
substring. title is the fragment of title expected
returns True when the title matches, False otherwise
"""
def _predicate(driver):
return title in driver.title
return _predicate
作用:
判断预期的浏览器标题是否存在于当前实际的浏览器标题中
传入参数:
title [传入预期的浏览器的标题名称]
返回值:
布尔值【True/False】
'''
03 alert_is_present
判断弹窗是否出现
'''
源码:
def alert_is_present():
def _predicate(driver):
try:
return driver.switch_to.alert
except NoAlertPresentException:
return False
return _predicate
作用:
判断弹窗是否出现
传入参数:
None
返回值:
存在且成功切换即返回driver.switch_to.alert,不存在/切换失败超时则返回False
'''
04 frame_to_be_available_and_switch_to_it
实现iframe内嵌框架的切换
# 代码演示
WebDriverWait(driver, 8).until(ec.frame_to_be_available_and_switch_to_it(
['id', 'if'])) # 属于元素定位器 - 可迭代,执行driver.switch_to.frame(driver.find_element(*locator))
WebDriverWait(driver, 8).until(
ec.frame_to_be_available_and_switch_to_it(0)) # 属于iframe索引值,不可迭代,执行driver.switch_to.frame(locator)
frame_ele = driver.find_element('id', 'if')
WebDriverWait(driver, 8).until(
ec.frame_to_be_available_and_switch_to_it(frame_ele)) # 属于webelement,不可迭代,执行driver.switch_to.frame(locator)
'''
源码:
def frame_to_be_available_and_switch_to_it(locator):
""" An expectation for checking whether the given frame is available to
switch to. If the frame is available it switches the given driver to the
specified frame.
"""
def _predicate(driver):
try:
if hasattr(locator, '__iter__'): # 如果传入的参数是可迭代对象
driver.switch_to.frame(driver.find_element(*locator))
else:
driver.switch_to.frame(locator)
return True
except NoSuchFrameException:
return False
return _predicate
作用:
实现iframe内嵌框架的切换
传入参数:
locator - 元素定位器,传入的可以是元素定位器,可以是索引,也可以是webelement
返回值:
True/False
'''
参考文章
发表评论