zoukankan      html  css  js  c++  java
  • 深入selenium三种等待方式使用

    深入selenium三种等待方式使用

    处理由于网络延迟造成没法找到网页元素

    方法一

    time模块不推荐使用

    用time模块中的time.sleep来完成等待

    from selenium import webdriver
    import time
    
    browser =  webdriver.Chrome()
    response = browser.get('https://www.12306.cn/index/')
    #找到登入按钮点击
    login_button_xpath = '//*[@id="J-header-login"]/a[1]'
    login_button = browser.find_element_by_xpath(login_button_xpath)
    while not login_button:
        login_button = browser.find_element_by_xpath(login_button_xpath)
        time.sleep(10)
    login_button.click()
    

    方法二

    implicitly_wait(隐式等待)

    • 隐式等待实际是设置了一个最长等待时间

    • 如果在规定时间内网页加载完成,则执行下一步,否则一直等到时间结束,然后执行下一步。

    • 注意点我们都知道js一般都是放在我们的body的最后进行加载,实际这是页面上的元素都已经加载完毕,我们却还在等带全部页面加载结束。

    • 隐式等待对整个driver周期都起作用,在最开始设置一次就可以了。不要当做固定等待使用,到那都来一下隐式等待。

    #隐式等待,失败概率高,可不用
    browser.implicitly_wait(10)
    #在10秒内,如果网页全部加载完成(包含js),则执行下一步,否则一直等到10秒结束后,在执行下一步
    

    方法三

    WebDriverWait(显示等待)(推荐使用)

    from selenium.webdriver.support.wait import WebDriverWait

    参数

    • driver: 传入WebDriver实例,即我们上例中的driver
    • timeout: 超时时间,等待的最长时间
    • poll_frequency: 调用until或until_not中的方法的间隔时间,默认是0.5秒
    • ignored_exceptions: 忽略的异常,如果在调用until或until_not的过程中抛出这个元组中的异常,则不中断码,继续等待,如果抛出的是这个元组外的异常,则中断代码,抛出异常。默认只有NoSuchElementException。

    until与until_not

    • until:当某元素出现或什么条件成立则继续执行
    • nutil_not:当某元素消失或什么条件不成立则继续执行

    until与until_not里面的两个参数

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

    method的设置

    必须是含有__call__的可执行方法。所以我们引用selenium提供的一个模块

    from selenium.webdriver.support import expected_conditions as EC

    EC相关汇总

    '''隐式等待和显示等待都存在时,超时时间取二者中较大的'''
    locator = (By.ID,'kw')
    driver.get(base_url)
     
    WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
    '''判断title,返回布尔值'''
     
    WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
    '''判断title,返回布尔值'''
     
    WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
    '''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''
     
    WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))
    '''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''
     
    WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
    '''判断元素是否可见,如果可见就返回这个元素'''
     
    WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))
    '''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表'''
     
    WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))
    '''判断是否至少有一个元素在页面中可见,如果定位到就返回列表'''
     
    WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))
    '''判断指定的元素中是否包含了预期的字符串,返回布尔值'''
     
    WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))
    '''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''
     
    #WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
    '''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
    #注意这里并没有一个frame可以切换进去
     
    WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
    '''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
    #注意#swfEveryCookieWrap在此页面中是一个隐藏的元素
     
    WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
    '''判断某个元素中是否可见并且是enable的,代表可点击'''
    driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
    #WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()
     
    #WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
    '''等待某个元素从dom树中移除'''
    #这里没有找到合适的例子
     
    WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
    '''判断某个元素是否被选中了,一般用在下拉列表'''
     
    WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))
    '''判断某个元素的选中状态是否符合预期'''
     
    WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
    '''判断某个元素的选中状态是否符合预期'''
    driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()
     
    instance = WebDriverWait(driver,10).until(EC.alert_is_present())
    '''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容'''
    

    By的相关汇总

    from selenium.webdriver.common.by import By

    BY对于的内容

    ID = "id"
    XPATH = "xpath"
    LINK_TEXT = "link text"
    PARTIAL_LINK_TEXT = "partial link text"
    NAME = "name"
    TAG_NAME = "tag name"
    CLASS_NAME = "class name"
    CSS_SELECTOR = "css selector"
    

    自定义expected_conditions

    class current_url(object):
        def __init__(self,current_url):
            self.current_url = current_url
        def __call__(self, driver):
            return self.current_url == driver.current_url
    

    使用举例

    from selenium import webdriver
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.common.by import By
    
    
    browser =  webdriver.Chrome()
    response = browser.get('https://www.12306.cn/index/')
    login_button_xpath = '//*[@id="J-header-login"]/a[1]'
    print(time.time())
    #每1秒扫描一次,直到60秒超时后,停止
    a=WebDriverWait(browser,60,1).until(EC.presence_of_element_located((By.XPATH,login_button_xpath)))
    login_button = browser.find_element_by_xpath(login_button_xpath)
    print(time.time())
    login_button.click()
    

    参考文档:http://www.imdsx.cn/index.php/2017/07/27/ec/

  • 相关阅读:
    Linux文件属性
    [Oracle] Listener的动态注册
    jQuery easyUI Pagination控件自定义div分页(不用datagrid)
    桂林电子科技大学出校流量控制器Android版1.0.0
    php使用check box
    Python windows ping
    Python selenium chrome 环境配置
    Linux wget auto login and backup database
    PyQt4 ShowHMDB show sqlite3 with QTableWidget summary
    PyQt4 py2exe 打包 HardwareManager
  • 原文地址:https://www.cnblogs.com/pythonywy/p/11284800.html
Copyright © 2011-2022 走看看