Selenium2+python自动化38-显式等待(WebDriverWait)

前言:

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

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

一、参数解释

1.这里主要有三个参数:

class WebDriverWait(object):driver, timeout, poll_frequency

2.driver:返回浏览器的一个实例,这个不用多说

3.timeout:超时的总时长

4.poll_frequency:循环去查询的间隙时间,默认0.5秒

以下是源码的解释文档(案例一个是元素出现,一个是元素消失)
    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())
        """

二、元素出现:until()

1.until里面有个lambda函数,这个语法看python文档吧

2.以百度输入框为例

三、元素消失:until_not()

1.判断元素是否消失,是返回Ture,否返回False

备注:此方法未调好,暂时放这

四、参考代码:

# coding:utf-8
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")
# 等待时长10秒,默认0.5秒询问一次
WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("kw")).send_keys("yoyo")

# 判断id为kw元素是否消失
is_disappeared = WebDriverWait(driver, 10, 1).\
    until_not(lambda x: x.find_element_by_id("kw").is_displayed())
print is_disappeared

 

五、WebDriverWait源码

1.WebDriverWait主要提供了两个方法,一个是until(),另外一个是until_not()

以下是源码的注释,有兴趣的小伙伴可以看下

# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

import time
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import TimeoutException

POLL_FREQUENCY = 0.5  # How long to sleep inbetween calls to the method
IGNORED_EXCEPTIONS = (NoSuchElementException,)  # exceptions ignored during calls to the method

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())
        """
        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)
学习过程中有遇到疑问的,可以加selenium(python+java) QQ群交流:646645429

selenium+python高级教程》已出书:selenium webdriver基于Python源码案例

(购买此书送对应PDF版本)

 

 

 

时间: 2024-09-23 18:11:13

Selenium2+python自动化38-显式等待(WebDriverWait)的相关文章

Selenium2+python自动化39-关于面试的题

前言 最近看到群里有小伙伴贴出一组面试题,最近又是跳槽黄金季节,小编忍不住抽出一点时间总结了下, 回答不妥的地方欢迎各位高手拍砖指点.   一.selenium中如何判断元素是否存在? 首先selenium里面是没有这个方法的,判断元素存在需要自己写一个方法了. 元素存在有几种形式,一种是页面有多个元素属性重复的,这种直接操作会报错的:还有一种是页面隐藏的元素操作也会报错 判断方法参考这篇:Selenium2+python自动化36-判断元素存在   二.selenium中hidden或者是di

Selenium2+python自动化47-判断弹出框存在(alert_is_present)

前言 系统弹窗这个是很常见的场景,有时候它不弹出来去操作的话,会抛异常.那么又不知道它啥时候会出来,那么久需要去判断弹窗是否弹出了. 本篇接着Selenium2+python自动化42-判断元素(expected_conditions)讲expected_conditions这个模块   一.判断alert源码分析 class alert_is_present(object):    """ Expect an alert to be present.""

Selenium2+python自动化23-富文本(自动发帖)

前言      富文本编辑框是做web自动化最常见的场景,有很多小伙伴遇到了不知道无从下手,本篇以博客园的编辑器为例,解决如何定位富文本,输入文本内容 一.加载配置     1.打开博客园写随笔,首先需要登录,这里为了避免透露个人账户信息,我直接加载配置文件,免登录了.       不懂如何加载配置文件的,看这篇Selenium2+python自动化18-加载Firefox配置 二.打开编辑界面     1.博客首页地址:bolgurl = "http://www.cnblogs.com/&qu

Selenium2+python自动化24-js处理富文本(带iframe)

前言     上一篇Selenium2+python自动化23-富文本(自动发帖)解决了富文本上iframe问题,其实没什么特别之处,主要是iframe的切换,本篇讲解通过js的方法处理富文本上iframe的问题 一.加载配置     1.打开博客园写随笔,首先需要登录,这里为了避免透露个人账户信息,我直接加载配置文件,免登录了.       不懂如何加载配置文件的,看这篇Selenium2+python自动化18-加载Firefox配置 二.打开编辑界面     1.博客首页地址:bolgur

Selenium2+python自动化29-js处理多窗口

前言 在打开页面上链接的时候,经常会弹出另外一个窗口(多窗口情况前面这篇有讲解:Selenium2+python自动化13-多窗口.句柄(handle)),这样在多个窗口之间来回切换比较复杂,那么有没有办法让新打开的链接在一个窗口打开呢? 要解决这个问题,得从html源码上找到原因,然后修改元素属性才能解决.很显然js在这方面是万能的,于是本篇得依靠万能的js大哥了. 一.多窗口情况     1.在打baidu的网站链接时,会重新打开一个窗口     (注意:我的百度页面是已登录状态,没登录时候

Selenium2+python自动化61-Chrome您使用的是不受支持的命令行标记:--ignore-certificate-errors

前言 您使用的是不受支持的命令行标记:--ignore-certificate-errors.稳定性和安全性会有所下降 selenium2启动Chrome浏览器是需要安装驱动包的,但是不同的Chrome浏览器版本号,对应的驱动文件版本号又不一样,如果版本号不匹配,是没法启动起来的.   一.Chrome遇到问题 1.如果在启动chrome浏览器时候,出现如下界面,无法打开网址,那么首先恭喜你,踩到了坑,接下来的内容或许对你有所帮助 >># coding:utf-8 >>from s

Selenium2+python自动化59-数据驱动(ddt)

前言 在设计用例的时候,有些用例只是参数数据的输入不一样,比如登录这个功能,操作过程但是一样的.如果用例重复去写操作过程会增加代码量,对应这种多组数据的测试用例,可以用数据驱动设计模式,一组数据对应一个测试用例,用例自动加载生成. 一.环境准备 1.安装ddt模块,打开cmd输入pip install ddt在线安装 >>pip install ddt   二.数据驱动原理 1.测试数据为多个字典的list类型 2.测试类前加修饰@ddt.ddt 3.case前加修饰@ddt.data() 4

Selenium2+python自动化55-unittest之装饰器(@classmethod)

前言 前面讲到unittest里面setUp可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间. 于是就想是不是可以只打开一次浏览器,执行完用例再关闭呢?这就需要用到装饰器(@classmethod)来解决了.   一.装饰器 1.用setUp与setUpClass区别 setup():每个测试case运行前运行 teardown():每个测试case运行完后执行 setUpClass():必须使用@classm

Selenium2+python自动化7-xpath定位

前言     在上一篇简单的介绍了用工具查看目标元素的xpath地址,工具查看比较死板,不够灵活,有时候直接复制粘贴会定位不到.这个时候就需要自己手动的去写xpath了,这一篇详细讲解xpath的一些语法. 什么是xpath呢? 官方介绍:XPath即为XML路径语言,它是一种用来确定XML1(标准通用标记语言3的子集)文档中某部分位置的语言.反正小编看这个介绍是云里雾里的,通俗一点讲就是通过元素的路径来查找到这个元素的,相当于通过定位一个对象的坐标,来找到这个对象. 一.xpath:属性定位

Selenium2+python自动化33-文件上传(send_keys)

前言 文件上传是web页面上很常见的一个功能,自动化成功中操作起来却不是那么简单. 一般分两个场景:一种是input标签,这种可以用selenium提供的send_keys()方法轻松解决: 另外一种非input标签实现起来比较困难,可以借助autoit工具或者SendKeys第三方库. 本篇以博客园的上传图片为案例,通过send_keys()方法解决文件上传问题 一.识别上传按钮 1.点开博客园编辑器里的图片上传按钮,弹出"上传本地图片"框. 2.用firebug查看按钮属性,这种上