• 5. selenium 三种等待方式原理剖析和场景应用


    前言

    UI 自动化一大困难点就是元素定位,而且最不稳定的就是页面,定位方法没问题,但是有时候网络不好,页面加载慢,也会导致找不到元素。

    找不到元素的时候selenium 会抛出类似的异常,NoSuchElementException

    为了解决页面等待问题,selenium 也专门设计了一些方法来进行页面等待,等待页面加载完成才开始定位元素,这样的话就会大大降低找不到元素的异常。


    等待方式有三种:

    1. Sleep 固定等待,等待时间到了,不管页面有没有加载完成,都会进行下一步。
    2. 隐式等待,implicitly_wait()。等待页面元素全部加载完成,进行下一步操作。
    3. 显式等待,WebDriverWait()。等待特定某个元素加载完成,进行下一步。

    一、sleep 固定等待

    在自动化测试过程中,不要用 sleep 方法进行等待,这样会导致整个项目的自动化测试无线延长,不建议使用。但是在调试脚本的时候可以使用,方便快捷。

    from selenium import webdriver
    from time import sleep                   # 导入sleep
    driver = webdriver.Chrome()
    
    url = 'https://movie.douban.com/'
    driver.get(url)
    
    sleep(5)                                 # 等待 5 s
    driver.find_element_by_name('search_text').send_keys('蜘蛛侠')
    
    sleep(2)
    
    driver.quit()                            # 关闭浏览器 
    


    二、implicitly_wait

    隐式等待是通过一定的时长等页面元素全部加载完成(就是等待页面左上角转圈结束)。如果超出了设置的时长,元素还没有加载出来,那么就会抛出异常 NoSuchElementException。

    否则一直等到时间结束,这里有不好的地方,因为 JavaScript 一般是放在 body 的最后进行加载,需要的元素加载完成了,我们却在等待页面全部加载完成,也是浪费时间。

    隐式等待对整个 driver 周期都起作用,在最开始设置一次就可以了。

    from selenium import webdriver
    from selenium.common.exceptions import NoSuchElementException
    driver = webdriver.Chrome()
    
    # 设置隐式等待,最多等待 10 s,如果 10s内什么时候加载完毕就什么时候进行操作
    driver.implicitly_wait(10)
    
    try:
        url = 'https://movie.douban.com/'
        driver.get(url)
        driver.find_element_by_name('search_text').send_keys('蜘蛛侠')
    
    except NoSuchElementException as msg:
        print(msg)
    
    # 关闭浏览器
    driver.quit()
    


    三、 显式等待 - WebDriverWait()

    显式等待是针对某一个元素进行等待判定,隐式等待是等待页面上全部加载完成,所以显式等待更加好,也是最常用的一种等待方式。

    WebDriverWait 是 selenium 提供显式等待的模块。

    class WebDriverWait(object):
        def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=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.
                - ignored_exceptions - iterable structure of exception classes ignored during calls.
                  By default, it contains NoSuchElementException only.
    
               Example:
                from selenium.webdriver.support.ui 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())
    

    参数说明:

    -driver            : 传入 WebDriver 实例
    -timeout           : 超时时间,等待的最长时间
    -poll_frequency    : 调用 until 或until_not 中的方法的间隔时间,默认是 0.5 s
    -ignored_exceptions: 忽略的异常
    

    这个模块中,有两种方法 until 和 until_not。

    -method  : 在等待期间,每隔一段时间调用这个传入的方法,直到返回值不是 False
    -message : 如果超时,抛出 TimeoutException,讲 message 传入异常。
    

    例子1:

    from selenium import webdriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    driver = webdriver.Chrome()
    
    url = 'https://movie.douban.com/'
    driver.get(url)
    
    # 一共等待 10s,每 0.5 查找一次,直到找到name 为 search_text 的元素。
    element = WebDriverWait(driver, 10, 0.5).until(lambda x: x.find_element_by_name("search_text"))
    element.send_keys('蜘蛛侠')
    


    例子2

    方式二、

    看看 expected_conditions 的源码,按住 ctrl 键,鼠标点击就可以过去源码这里。
    有判断 title 的方法,有url 的,也有 alert 弹窗的,根据实际情况选择即可。

    
    from selenium import webdriver
    from selenium.webdriver.support.wait import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    driver = webdriver.Chrome()
    
    url = 'https://movie.douban.com/'
    driver.get(url)
    
    # 最多等待 5 s,每 0.5 秒查找一次。
    wait = WebDriverWait(driver, 5, 0.5)
    # 直到在这个页面出现 title 为 豆瓣电影
    wait.until(EC.title_is('豆瓣电影'))
    
    driver.find_element_by_name('search_text').send_keys('蜘蛛侠')
    
    
  • 相关阅读:
    在Ubuntu下安装TensorFlow-gpu版本
    ubuntu安装和卸载软件命令
    Window7通过Anaconda安装Tensorflow
    Kaggle Titanic Data Science Solutions
    CNN、RNN和DNN的区别
    卷积神经网络介绍
    大数据随想
    golang omitempty 总结
    LeetCode 856 递归思路详解
    安装Nginx的各种报错的解决
  • 原文地址:https://www.cnblogs.com/wwho/p/16061754.html
Copyright © 2020-2023  润新知