【selenium】三种等待方式

selenium 三种等待方式演示。

  • 强制等待
  • 隐式等待
  • 显式等待

强制等待

import time
# 整个程序强制等待 3 秒
time.sleep(3)

隐式等待

设置一个全局的等待时间,以隐式等待找到元素或完成命令。每个会话只需要调用一次此方法。

# Amount of time to wait (in seconds)
driver.implicitly_wait(3)

显式等待

定义等待条件,满足条件才继续向下执行,否则继续等待,超时后抛出异常。更加灵活的等待方式,项目中最常用的等待方式。

显示等待类 WebDriverWait 初始化接收四个参数

  • driver:自动化驱动
  • timeout:总等待时间
  • poll_frequency:轮询间隔时间
  • ignored_exceptions:忽略预期的异常类型

两个判断条件:

def until(self, method, message=''):
  """
  调用传入的方法作为参数,直到返回值不是 False
  """

def until_not(self, method, message=''):
  """
  调用传入的方法作为参数,直到返回值为 False
  """

示例

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import StaleElementReferenceException


class TestWait:
    def setup_class(self):
        self.driver = webdriver.Chrome()
        self.driver.get("https://www.baidu.com")
        self.driver.implicitly_wait(5)  # 隐式等待

    def teardown_class(self):
        self.driver.quit()

    def test_sleep(self):
        """ 强制等待
        无论元素是否出现都强制等待
        """
        ele = self.driver.find_element(By.ID, "kw")
        time.sleep(10)
        ele.send_keys("hello")

    def test_implicitly_wait(self):
        """ 隐式等待
        设置在初始化 driver 处,元素 5 秒不出现才报错
        """
        ele = self.driver.find_element(By.ID, "test")  # 随便设置个元素
        ele.click()

    def test_webdriver_wait_by_def(self):
        """ 显式等待
        自定义方法编写条件
        """
        def wait(x):  # 参数为必传项
            hot_search_items = self.driver.find_elements(
                By.XPATH, '//*[@class="title-content-title"]'
            )
            return len(hot_search_items) == 6
        # 等待百度热搜出现 6 条则继续向下执行,否则最大等待时间为 10 秒,0.5 秒轮询一次
        WebDriverWait(self.driver, 10).until(wait)

    def test_webdriver_wait_by_ec(self):
        """ 显式等待
        使用预置的等待条件库 expected_conditions
        """
        # 等待热搜词可点击才继续向下执行,否则最大等待时间为 10 秒,每秒轮询一次
        WebDriverWait(self.driver, 1, 10).until(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, '//*[@class="title-content-title"]')
            )
        )

    def test_webdriver_wait_until_not(self):
        """ 显式等待
        每 5 秒看一次该元素是否展示,如果不展示则用例直接通过
        """
        WebDriverWait(self.driver, 5, 10).until_not(
            expected_conditions.element_to_be_clickable(
                (By.XPATH, 'hello')
            )
        )

    def test_webdriver_wait_ignored_exceptions(self):
        """ 显式等待
        忽略某种预期内的异常,继续轮询等待
        """
        WebDriverWait(self.driver, 1, 5, StaleElementReferenceException).until(
            # 可以在 WebDriverWait 初始化时添加忽略异常, 如上当页面元素未更新时也不会报错,继续轮询
            # 默认为 NoSuchElementException
            expected_conditions.element_to_be_clickable(
                (By.ID, "test")
            )
        )

expected_conditions API
"""
 * Canned "Expected Conditions" which are generally useful within webdriver
 * tests.
"""

class title_is(object):
    """标题完全匹配,返回 bool"""
class title_contains(object): 
    """标题包含匹配,区分大小写"""

class url_contains(object):
    """url 片段匹配,区分大小写,返回 bool"""
class url_matches(object):
    """url 正则匹配,返回 bool"""
class url_to_be(object):
    """url 精确匹配,返回 bool"""
class url_changes(object):
    """url 不匹配则为真,否则为假"""

class presence_of_element_located(object):
	"""页面元素是否存在,并不一定可见,接收一个 locator"""
class visibility_of_element_located(object):
    """元素是否在页面中必须展示,且高度宽度大于0,接收一个 locator"""
class visibility_of(object):
    """元素是否可见,可见则返回元素,否则返回 false"""
class presence_of_all_elements_located(object):
    """查找一组元素,无论是否在页面可见"""
class visibility_of_any_elements_located(object):
    """查找一组元素,返回该元素中所有在页面可见的元素"""
class visibility_of_all_elements_located(object):
    """查找一组元素,该元素都页面中可见"""

class text_to_be_present_in_element(object):
    """检查指定文本是否存在于元素的文本当中"""
class text_to_be_present_in_element_value(object):
    """检查指定文本是否存在于元素的属性值当中"""

class frame_to_be_available_and_switch_to_it(object):
    """检查是否可以切换到指定 locator 的 frame 当中"""

class invisibility_of_element_located(object):
    """ 元素在页面中不可见或不存在 """
class element_to_be_clickable(object):
    """元素是否可被点击"""
class staleness_of(object):
    """元素是否停止加载,依然加载返回 false,否则为 true"""
class element_to_be_selected(object):
    """获取元素对象的 is_selected 属性"""
class element_located_to_be_selected(object):
    """通过 locator 定位元素,获取该元素的 is_selected 属性"""
class element_selection_state_to_be(object):
    """当前元素是否为选中状态"""
class element_located_selection_state_to_be(object):
    """当前元素是否可被选中"""

class number_of_windows_to_be(object):
    """判断当前浏览器窗口数量"""
class new_window_is_opened(object):
    """检查是否打开了一个新窗口"""
class alert_is_present(object):
    """alert 弹窗是否chu'xian"""

显式等待 + 窗口切换官方示例

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

with webdriver.Chrome() as driver:
    # Open URL
    driver.get("https://www.baidu.com")

    # Setup wait for later
    wait = WebDriverWait(driver, 10)

    # Store the ID of the original window
    original_window = driver.current_window_handle

    # Check we don't have other windows open already
    assert len(driver.window_handles) == 1

    # Click the link which opens in a new window
    driver.find_element(By.LINK_TEXT, "新闻").click()

    # Wait for the new window or tab
    wait.until(EC.number_of_windows_to_be(2))

    # Loop through until we find a new window handle
    for window_handle in driver.window_handles:
        if window_handle != original_window:
            driver.switch_to.window(window_handle)
            break

    # Wait for the new tab to finish loading content
    wait.until(EC.title_is("百度新闻——海量中文资讯平台"))

猜你喜欢

转载自blog.csdn.net/lan_yangbi/article/details/127968271