WebDriverWait显示等待源码剖析

我们在使用selenium 查找元素的时候,为了避免网页加载慢,会加一个sleep(x秒)

这样能解决加载慢的问题,但也存在2个问题

1.如果你设置的等待时间过了,还没加载出来,就会报“NoSuchElementException”

2.如果设置等待5秒,2秒就加载出来了,也还是会再等3秒,这样影响执行效率

有什么好的方法呢?

当然是有的,selenium.webdriver.support.wait下有一个 WebDriverWait类,就能很好的解决上面的问题

具体用法如下

from selenium.webdriver.support.wait import WebDriverWait
from selenium import webdriver
driver = webdriver.Chrome()
elem = WebDriverWait(driver, 5).until(lambda driver: driver.find_element_by_id(‘su’))
elem.click()

初始化WebDriverWait,传入driver,最长等待时间5秒

调用util方法,utile接收一个方法

我们来看下源码

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

POLL_FREQUENCY = 0.5  # 没0.5秒调用一下util接收到的方法
IGNORED_EXCEPTIONS = (NoSuchElementException,)  # 忽略遇到异常

class WebDriverWait(object):
    def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
        """     此处省略注释"""
        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)
WebDriverWait构造方法需要接收driver和timeout(超时时间),默认调用频率poll_frequency(0.5秒)
until方法中主要是这一段
value = method(self._driver)
if value:
   return value

 执行接收的方法,如果接收方法执行OK,则直接返回入参方法的返回值

即我们传入的driver.find_element_by_id(‘su’),会返回元素

原文地址:https://www.cnblogs.com/easy-test/p/12143482.html

时间: 2024-08-26 05:57:44

WebDriverWait显示等待源码剖析的相关文章

DICOM医学图像处理:storescp.exe与storescu.exe源码剖析,学习C-STORE请求

背景: 上一篇专栏博文中针对PACS终端(或设备终端,如CT设备)与RIS系统之间worklist查询进行了介绍,并着重对比分析了DICOM3.0中各部分对DICOM网络通讯服务的定义.此次通过结合早些时间的博文DICOM医学图像处理:基于DCMTK工具包学习和分析worklist,对DCMTK开源库中提供的storescp.exe和storescu.exe工具的源码进行剖析,从底层深入了解C-STORE服务的触发及响应. 分析思路: storescp.exe和storescu.exe分别充当着

豆瓣Redis解决方案Codis源码剖析:Dashboard

豆瓣Redis解决方案Codis源码剖析:Dashboard 1.不只是Dashboard 虽然名字叫Dashboard,但它在Codis中的作用却不可小觑.它不仅仅是Dashboard管理页面,更重要的是,它负责监控和指挥各个Proxy的负载均衡(数据分布和迁移).并且,所有API都以RESTFul接口的形式对外提供,供Proxy和codis-config(Codis的命令行工具)调用.下面就来看一下数据分布和迁移的代码执行流程. Dashboard涉及到的知识点比较多,包括Martini框架

Phaser实现源码剖析

在这里首先说明一下,由于Phaser在4.3代码里是存在,但并没有被开放出来供使用,但已经被本人大致研究了,因此也一并进行剖析. Phaser是一个可以重复利用的同步栅栏,功能上与CyclicBarrier和CountDownLatch相似,不过提供更加灵活的用法.也就是说,Phaser的同步模型与它们差不多.一般运用的场景是一组线程希望同时到达某个执行点后(先到达的会被阻塞),执行一个指定任务,然后这些线程才被唤醒继续执行其它任务. Phaser一般是定义一个parties数(parties一

菜鸟nginx源码剖析 框架篇(一) 从main函数看nginx启动流程(转)

俗话说的好,牵牛要牵牛鼻子 驾车顶牛,处理复杂的东西,只要抓住重点,才能理清脉络,不至于深陷其中,不能自拔.对复杂的nginx而言,main函数就是“牛之鼻”,只要能理清main函数,就一定能理解其中的奥秘,下面我们就一起来研究一下nginx的main函数. 1.nginx的main函数解读 nginx启动显然是由main函数驱动的,main函数在在core/nginx.c文件中,其源代码解析如下,涉及到的数据结构在本节仅指出其作用,将在第二节中详细解释. nginx main函数的流程图如下:

《STL源码剖析》---stl_iterator.h阅读笔记

STL设计的中心思想是将容器(container)和算法(algorithm)分开,迭代器是容器(container)和算法(algorithm)之间的桥梁. 迭代器可以如下定义:提供一种方法,能够依序寻访某个容器内的所有元素,而又无需暴露该容器的内部表达方式. 在阅读代码之前,要先了解一个新概念:Traits编程技法 template <class T> struct MyIter { typedef T value_type //内嵌型别声明 T *ptr; MyIter(T *p = 0

Nodejs事件引擎libuv源码剖析之:高效线程池(threadpool)的实现

声明:本文为原创博文,转载请注明出处. Nodejs编程是全异步的,这就意味着我们不必每次都阻塞等待该次操作的结果,而事件完成(就绪)时会主动回调通知我们.在网络编程中,一般都是基于Reactor线程模型的变种,无论其怎么演化,其核心组件都包含了Reactor实例(提供事件注册.注销.通知功能).多路复用器(由操作系统提供,比如kqueue.select.epoll等).事件处理器(负责事件的处理)以及事件源(linux中这就是描述符)这四个组件.一般,会单独启动一个线程运行Reactor实例来

STL&quot;源码&quot;剖析-重点知识总结

STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合套用: 容器(Containers):各种数据结构,如:vector.list.deque.set.map.用来存放数据.从实现的角度来看,STL容器是一种class template. 算法(algorithms):各种常用算法,如:sort.search.copy.erase.从实现的角度来看,STL算法

豆瓣Redis解决方案Codis源码剖析:Proxy代理

豆瓣Redis解决方案Codis源码剖析:Proxy代理 1.预备知识 1.1 Codis Codis就不详细说了,摘抄一下GitHub上的一些项目描述: Codis is a proxy based high performance Redis cluster solution written in Go/C, an alternative to Twemproxy. It supports multiple stateless proxy with multiple redis instan

Python源码剖析笔记0 ——C语言基础

python源码剖析笔记0--C语言基础回顾 要分析python源码,C语言的基础不能少,特别是指针和结构体等知识.这篇文章先回顾C语言基础,方便后续代码的阅读. 1 关于ELF文件 linux中的C编译得到的目标文件和可执行文件都是ELF格式的,可执行文件中以segment来划分,目标文件中,我们是以section划分.一个segment包含一个或多个section,通过readelf命令可以看到完整的section和segment信息.看一个栗子: char pear[40]; static