• Selenium3+python3自动化(二十七)--webdriver中等待,显式等待(WebDriverWait),强制等待sleep(),隐式等待implicitly_wait()


    前言

    在脚本中加入太多的sleep后会影响脚本的执行速度,虽然implicitly_wait()这种方式隐式等待方法一定程度上节省了很多时间。

    但是一旦页面上某些js无法加载出来(其实界面元素已经出来了),左上角那个图标一直转圈,这时候会一直等待的。

    一、WebDriverWait参数解释

    1.WebDriverWait有4个参数:

    WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)  

    需要通过 from selenium.webdriver.support.wait import WebDriverWait 导入模块

    • driver:返回浏览器的一个实例,浏览器驱动
    • timeout:超时的总时长,默认以秒为单位
    • poll_frequency:循环去查询的间隙时间,默认0.5秒
    • ignored_exceptions:超时后的抛出的异常信息,默认抛出NoSuchElementException异常

    以下是源码的解释文档

    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 
    
                element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId")) 
    
                is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)). 
    
                            until_not(lambda x: x.find_element_by_id("someId").is_displayed())
            """
            self._driver = driver
            self._timeout = 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 is not None:
                try:
                    exceptions.extend(iter(ignored_exceptions))
                except TypeError:  # ignored_exceptions is not iterable
                    exceptions.append(ignored_exceptions)
            self._ignored_exceptions = tuple(exceptions)
    
        def __repr__(self):
            return '<{0.__module__}.{0.__name__} (session="{1}")>'.format(
                type(self), self._driver.session_id)
    
        def until(self, method, message=''):
            """Calls the method provided with the driver as an argument until the 
            return value is not False."""
            screen = None
            stacktrace = None
    
            end_time = time.time() + self._timeout
            while True:
                try:
                    value = method(self._driver)
                    if value:
                        return value
                except self._ignored_exceptions as exc:
                    screen = getattr(exc, 'screen', None)
                    stacktrace = getattr(exc, 'stacktrace', None)
                time.sleep(self._poll)
                if time.time() > end_time:
                    break
            raise TimeoutException(message, screen, stacktrace)
    
        def until_not(self, method, message=''):
            """Calls the method provided with the driver as an argument until the 
            return value is False."""
            end_time = time.time() + self._timeout
            while True:
                try:
                    value = method(self._driver)
                    if not value:
                        return value
                except self._ignored_exceptions:
                    return True
                time.sleep(self._poll)
                if time.time() > end_time:
                    break
            raise TimeoutException(message)
    

     与until()或者until_not()方法结合使用

    WebDriverWait(driver,10).until(method,message="")
    #调用该方法提供的驱动程序作为参数,直到返回值为True
    
    WebDriverWait(driver,10).until_not(method,message="")
    #调用该方法提供的驱动程序作为参数,直到返回值为False 

     在设置时间(10s)内,等待后面的条件发生。如果超过设置时间未发生,则抛出异常。

    在等待期间,每隔一定时间(默认0.5秒),调用until或until_not里的方法,直到它返回True或False。

    WebDriverWait与expected_conditions结合使用

    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    wait = WebDriverWait(driver,10,0.5)
    element =waite.until(EC.presence_of_element_located((By.ID,"kw"),message=""))
    # 此处注意,如果省略message=“”,则By.ID外面是两层()
    

     如下实例,使用了匿名函数lambda、expected_condtions的presence_of_element_located方法(判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见)

    # 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.Chrome()
    driver.get("https://www.baidu.com")
    WebDriverWait(driver, 10, 0.5).until(EC.presence_of_element_located((By.ID, "kw"))).send_keys("xixi")
    WebDriverWait(driver,3).until(EC.presence_of_element_located(("id","kw"))).send_keys("_on_")
    WebDriverWait(driver,5).until(lambda x: x.find_element("id","kw")).send_keys("_good_")
    WebDriverWait(driver, 10, 0.5).until_not(lambda driver: driver.find_element_by_id("kw")).send_keys("hehe")
    
    # a=lambda x:x+22
    # print(a(5))
    

     运行结果:

    Traceback (most recent call last):
      File "E:/study/selenium_study/a825.py", line 12, in <module>
        WebDriverWait(driver, 10, 0.5).until_not(lambda driver: driver.find_element_by_id("kw")).send_keys("hehe")
      File "D:Program Filespython37libsite-packagesseleniumwebdriversupportwait.py", line 96, in until_not
        raise TimeoutException(message)
    selenium.common.exceptions.TimeoutException: Message:   

    二、强制等待:sleep()

    import time
    sleep(5)    #等待5秒
    

     设置固定休眠时间,单位为秒。由python的time包提供,导入time包后就可以使用。

    缺点:不智能,使用太多的sleep会影响脚本运行速度。

    三、隐式等待:implicitly_wait()

    driver.implicitly_wait(10)    #隐式等待10秒
    

     由webdriver提供的方法,一旦设置,这个隐式等待会在WebDriver对象实例的整个生命周期起作用,它不针对某一个元素,是全局元素等待,即在定位元素时,需要等待页面全部元素加载完成,才会执行下一个语句。如果超出 了设置时间的则抛出异常。

    缺点:当页面某些js无法加载,但是想找的元素已经出来了,它还是会继续等待,知道页面加载完成(浏览器标签左上角圈圈不再转),才会执行下一句。某些情况下会影响脚本执行速度。

      

    越努力,越幸运!!! good good study,day day up!!!
  • 相关阅读:
    12 python json&pickle&shelve模块
    11 python shutil 模块
    10 python os&sys 模块
    9 random模块
    8 python time$datetime
    7 python 模块间相互导入
    6 unit3-文件操作&函数 review
    3 Python 函数介绍
    hibernate课程 初探单表映射2-6 session详解(下)
    hibernate课程 初探单表映射2-5 session详解(上)
  • 原文地址:https://www.cnblogs.com/canglongdao/p/13596782.html
Copyright © 2020-2023  润新知