selenium自动化(中)

news2024/7/4 4:22:55

显式等待与隐式等待

简介

在实际工作中等待机制可以保证代码的稳定性,保证代码不会受网速、电脑性能等条件的约束。

等待就是当运行代码时,如果页面的渲染速度跟不上代码的运行速度,就需要人为的去限制代码执行的速度。

在做 Web 自动化时,一般要等待页面元素加载完成后,才能执行操作,否则会报找不到元素等各种错误,这样就要求在有些场景下加上等待。

最常见的有三种等待方式:隐式等待、显式等待、强制等待,下面介绍以下这三种等待方式。

隐式等待

设置一个等待时间,轮询查找(默认 0.5 秒)元素是否出现,如果没出现就抛出异常。这也是最常见的等待方法。

隐式等待的作用是全局的,是作用于整个 session 的生命周期,也就是说只要设置一次隐式等待,后面就不需要设置。如果再次设置隐式等待,那么后一次的会覆盖前一次的效果。

当在 DOM 结构中查找元素,且元素处于不能立即交互的状态时,将会触发隐式等待。

self.driver.implicitly_wait(30)

显式等待

显式等待是在代码中定义等待条件,触发该条件后再执行后续代码,就能够根据判断条件进行等待。程序每隔一段时间进行条件判断,如果条件成立,则执行下一步,否则继续等待,直到超过设置的最长时间。核心用法如下:

# 导入显式等待
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
...
# 设置10秒的最大等待时间,等待 (By.TAG_NAME, "title") 这个元素点击
WebDriverWait(driver, 10).until(
    expected_conditions.element_to_be_clickable((By.TAG_NAME, "title"))
)
...

这里通过导入 expected_conditions 这个库来满足显式等待所需的使用场景,但是 expected_conditions 库并不能满足所有场景,这个时候就需要定制化开发来满足特定场景。

实战演示

假设:要判断某个元素超过指定的个数,就可以执行下面的操作。

def ceshiren():
    # 定义一个方法
    def wait_ele_for(driver):
        # 将找到的元素个数赋值给 eles
        eles = driver.find_elements(By.XPATH, '//*[@id="site-logo"]')
        # 放回结果
        return len(eles) > 0
    driver = webdriver.Chrome()
    driver.get('https://ceshiren.com')
    # 显式等待10秒,直到 wait_ele_for 返回 true
    WebDriverWait(driver, 10).until(wait_ele_for)

强制等待

强制等待是使线程休眠一定时间。强制等待一般在隐式等待和显式等待都不起作用时使用。示例代码如下:

# 等待十秒
time.sleep(10)

实战演示

访问测试人社区(https://ceshiren.com),点击分类,然后点击开源项目:

当点击分类时,元素还未加载完成,这里就需要隐式等待。在点击开源项目时,元素已加载完成,但是还处在不可点击的状态,这时要用到显式等待。

web控件定位与常见操作

简介

在做 Web 自动化时,最根本的就是操作页面上的元素,首先要能找到这些元素,然后才能操作这些元素。工具或代码无法像测试人员一样用肉眼来分辨页面上的元素。那么要如何定位到这些元素,本章会介绍各种定位元素的方法。

web控件定位

通过id

Selenium 自带 id 定位,可以通过元素的 id 属性进行定位,以下代码演示。

driver.find_element(By.ID,'query')
通过name

Selenium 自带 name 定位,可以通过元素的 name 属性进行定位,以下代码演示。

driver.find_element(By.NAME,'query')

通常来说 name 属性与 id 属性在页面中唯一,推荐使用这两个属性进行定位。

通过XPath

XPath 是一个定位语言,英文全称为:XML Path Language,用来对 XML 上的元素进行定位,但也适用于 HTML,下面来看一个例子。

要定位的元素是Sogou首页的搜索输入框。

首先寻找 id 为 sf 的 form 元素,然后再寻找它的子元素 span,span 的 class 属性为 sec-input-box,最后找 span 的子元素 input,以下代码演示。

driver.find_element(By.XPATH,"//form[@id='sf']/span[@class='sec-input-box']/input")

下面的定位也可以找到这个 input,请注意,这里使用了双斜杠//,它可以找到子孙节点,而但斜杠/只能找到子节点,以下代码演示。

driver.find_element(By.XPATH,"//form[@id='sf']//input[@id='query']")

XPath 表达式更多内容可参考下面表格。

表达式描述
nodename选取此节点的所有子节点。
/从根节点选取。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点。
..选取当前节点的父节点。
@选取属性。

如何检验 XPath 定位是否正确?可以使用 chrome 的检查模式 -> Console,输入$x('XPath 表达式')即可。

通过css_selector

XPath 可以定位绝大多数元素,但是XPath采用从上到下的遍历模式,速度并不快,而 css_selector 采用样式定位,速度要优于 XPath,而且语法更简洁。下面是 Selenium 使用 css_selector 的例子。

css_selector 找到 class 属性为 active 的元素,然后 > 表示找 class 属性为 active 的元素的子节点,以下代码演示。

driver.driver.find_element(By.CSS_SELECTOR,'.logo-big')

下表列出了常用的 css_selector 表达式的用法。

表达式描述
.introclass="intro" 的所有元素
#firstnameid="firstname" 的所有元素
a[target=_blank]具有属性 target="_blank" 的所有 a 元素
p:nth-child(2)属于其父元素的第二个 p 元素

使用 Chrome 的检查模式 -> Console 也可以在当前页面检测 css_selector 是否正确,输入$('css selector 表达式')即可。

元素中会出现文字,比如下面的分类,可以利用这段文字进行定位,以下是代码演示。

driver.driver.find_element(By.LINK_TEXT, '欢迎光临测试人社区 | Powered by 霍格沃兹测试开发学社')

也可以采用部分匹配方式,不必写全:“欢迎光临”、“欢迎光临测试人社区”、“霍格沃兹”,以下是代码演示。

driver.find_element(By.PARTIAL_LINK_TEXT, '测试人社区')

要注意partial_link_text 与 link_text 的区别,partial_link_text 不用写全,只需写部分即可,比如上面使用“霍格沃兹”即可匹配到“欢迎光临霍格沃兹测试学院”。

通过tag_name

DOM 结构中,元素都有自己的 tag,比如 input tag,button tag,anchor tag 等等,每一个 tag 拥有多个属性,比如 id,name,value class等等。

下面的高亮部分就是 tag:

可以使用 tag 进行定位:

driver.driver.find_element(By.TAG_NAME,'input')

要注意,尽量避免使用 tag_name 定位元素,因为有大量重复的元素!

通过class_name

可以通过元素的 class 属性值进行定位:

这里的 active 用的就是上图 class 的值。

driver.driver.find_element(By.CLASS_NAME, 'active')
推荐使用

1)ID/Name 是最安全的定位选项。根据 W3C 标准,它在页面中是唯一的,ID 在树结构中也是唯一的。 2)CSS Selector 语法简洁,搜索速度快于 XPath。 3)XPath 定位功能强大,采用遍历搜索,速度略慢。 4)link,class name, tag name:不推荐使用,无法精准定位。

常见操作

Selenium 常见操作有:

  1. 输入、点击、清除。
  2. 关闭窗口、浏览器。
  3. 获取元素属性。
  4. 获取网页源代码、刷新页面。
  5. 设置窗口大小。
输入、点击、清除

输入、点击、清除在 Selenium 中对应的方法分别是 send_keys、click、clear,以下代码演示。

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http://www.baidu.com')
driver.find_element(By.NAME,'wd').send_keys('霍格沃兹测试学院')
driver.find_element(By.ID,'su').click()
driver.find_element(By.NAME,'wd').clear()
关闭窗口、浏览器

关闭当前句柄窗口(不关闭进程)close(),关闭整个浏览器进程 quit(),以下代码演示。

#导入对应的依赖
from selenium import webdriver
#初始化webdriver
driver = webdriver.Chrome()
#访问网站
driver.get('http"//www.baidu.com')
#关闭当前窗口
driver.close()
#关闭浏览器
driver.quit()
获取元素属性

获取元素标签上的属性 get_attribute('value'),元素的坐标 location,元素的大小 size,以下代码演示。

import logging
from selenium import webdriver

def test_baidu():
    driver = webdriver.Chrome()
    driver.get('https://www.baidu.com')
    search = driver.find_element(By.ID,'su')
    logging.basicConfig(level=logging.INFO)
    logging.info(search.get_attribute('value'))
    #获取search的value属性值并打印
    logging.info(search.get_attribute('value'))
    #打印search的位置坐标
    logging.info(search.location)
    #打印search的元素大小
    logging.info(search.size)

输出结果为:

INFO:root:百度一下
INFO:root:百度一下
INFO:root:{'x': 844, 'y': 188}
INFO:root:{'height': 44, 'width': 108}
获取网页源代码、刷新页面

网页源代码 page_source,刷新页面 refresh()。

import logging
from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http"//www.baidu.com')
#刷新页面
driver.refresh()
logging.basicConfig(level=logging.INFO)
#打印当前页面的源代码
logging.info(driver.page_source)
设置窗口大小

设置窗口大小主要有最小化、最大化和自定义设置窗口具体的大小。

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('http"//www.baidu.com')
#最小化窗口
driver.minimize_window()
#最大化窗口
driver.maximize_window()
#将浏览器设置为1000*1000的大小
driver.set_window_size(1000, 1000)
#导入依赖
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait

class TestHogwarts():
    def setup(self):
        self.driver = webdriver.Chrome()
        self.driver.get('https://ceshiren.com/')
        # 加入隐式等待
        self.driver.implicitly_wait(5)

    def teardown(self):
        # 强制等待
        time.sleep(10)
        self.driver.quit()

    def test_hogwarts(self):
        # 点击类别
        self.driver.find_element(By.CSS_SELECTOR, '[title="按类别分组的所有话题"]').click()
        # 元素定位,这里的category_name是一个元组。
        category_name = (By.XPATH, "//*[@class='category-text-title']//*[text()='开源项目']")
        # 加入显式等待
        WebDriverWait(self.driver, 10).until(
            expected_conditions.element_to_be_clickable(category_name))
        # 点击开源项目
        self.driver.find_element(*category_name).click()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1305637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

经典策略筛选-20231212

策略1: 龙头战法只做最强:国企改革 ----四川金顶 1、十日交易内出现 涨停或 (涨幅大于7个点且量比大于3) 2、JDK MACD RSI OBV BBI LWR MTM 六指标共振 3、均线多头 4、 筹码峰 (锁仓) 5、现价>…

虹科分享 | CanEasy多场景应用,让汽车总线测试更简单

CanEasy是一个基于Windows的总线工具,用于分析和测试CAN、CAN FD和LIN以及汽车以太网系统。通过高度自动化和简单的配置模拟总线流量,CanEasy可用于分析真实网络、模拟虚拟系统,以及在整个开发过程中进行剩余总线模拟,实现从测试到…

FFmpeg-基础组件-AVFrame

本章主要介绍FFmpeg基础组件AVFrame. 文章目录 1.结构体成员2.成员函数AVFrame Host内存的获取 av_frame_get_bufferAVFrame device内存获取av_hwframe_get_buffer() 1.结构体成员 我们把所有的代码先粘贴上来,在后边一个一个解释。 typede…

鸿蒙Stage模型开发—创建你的第一个ArkTS应用

Stage模型开发概述 基本概念 下图展示了Stage模型中的基本概念。 图1 Stage模型概念图 UIAbility组件和ExtensionAbility组件 Stage模型提供UIAbility和ExtensionAbility两种类型的组件,这两种组件都有具体的类承载,支持面向对象的开发方式。UIAbility…

ARM:作业3

按键中断代码编写 代码: key_it.h #ifndef __KEY_IT_H__ #define __KEY_IT_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_exti.h" #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gic.h"void key1_it_config(); voi…

冯诺依曼体系与操作系统的理解

目录 一.冯诺依曼体系结构 存储分级 为什么程序运行之前,必须加载到内存上? 二.操作系统 操作系统是什么? 为什么需要操作系统? 操作系统是如何管理软硬件资源? 一.冯诺依曼体系结构 我们常见的计算机&#xff…

Qt 容器QGroupBox带有标题的组框框架

控件简介 QGroupBox 小部件提供一个带有标题的组框框架。一般与一组或者是同类型的部件一起使用。教你会用,怎么用的强大就靠你了靓仔、靓妹。 用法示例 例 qgroupbox,组框示例(难度:简单),使用 3 个 QRadioButton 单选框按钮,与QVBoxLayout(垂直布局)来展示组框的…

BearPi Std 板从入门到放弃 - 先天神魂篇(2)(RT-Thread LED PWM驱动)

简介 基于 BearPi Std 板从入门到放弃 - 先天神魂篇(1)(RT-Thread 指令点亮LED) 创建的项目, 添加PWM驱动LED的方式实现呼吸灯功能, 电路板及相关使用到的配件说明 开发板 : Bearpi Std(小熊派标准板) 主芯片: STM32L431RCT6 E53_ST1扩展板/…

【acwing】92. 递归实现指数型枚举

穿越隧道 递归枚举、位运算 方法① 从1到n&#xff0c;顺序访问每位数&#xff0c;是否选择&#xff0c;每位数有两种状态&#xff0c;选1或不选0. AC代码如下&#xff1a; #include <iostream> using namespace std;const int N 100; // bool st[N]; int n;void dfs(in…

智能优化算法应用:基于指数分布算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于指数分布算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于指数分布算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.指数分布算法4.实验参数设定5.算法结果6.参考…

优雅玩转实验室服务器(一)登录服务器

这篇文章更加偏向于使用python程序进行研究的朋友们 原料 Windows主机实验室Linux服务器&#xff08;可以访问互联网&#xff09;一点点耐心 step.0 windows terminal is all you need 别跟我说什么putty&#xff0c;什么winscp&#xff0c;我就是单推Win11自带的软件——win…

DNS漫游指南:从网址到IP的奇妙之旅

当用户在浏览器中输入特定网站时发生的整个端到端过程可以参考下图 1*4vb-NMUuYTzYBYUFSuSKLw.png 问题&#xff1a; 什么是 DNS&#xff1f; 答案 → DNS 指的是域名系统&#xff08;Domain Name System&#xff09;。DNS 是互联网的目录&#xff0c;将人类可读的域名&#…

佛山陶企再造行业新风口,开启中国陶瓷下半场

近年来&#xff0c;消费形态逐渐呈现年轻化、时尚化、数字化的趋势&#xff0c;新一地居住者对于居住环境的品质和舒适度要求日益提高。伴随着新消费势力的崛起&#xff0c;家居建材行业消费转型升级已成必然。“千年陶都”佛山作为我国陶瓷行业的风向标&#xff0c;率先推进技…

漏洞复现-云安宝-云匣子Fastjson命令执行(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

在做题中学习(32):只出现一次的数字 III

260. 只出现一次的数字 III - 力扣&#xff08;LeetCode&#xff09; 根据题目可知&#xff1a;有两个元素只出现一次&#xff0c;其余出现两次。 而在只出现一次的数字 I 里&#xff0c;只有一个元素出现一次&#xff0c;可以用异或的方式直接得到最后的答案&#xff0c;而此…

基于导数Zernike多项式拟合技术的干涉测量二维相位展开算法(原文翻译)

Zixin Zhao1&#xff0c;Hong Zhao1、Lu Zhang 1&#xff0c;Fen Gao2&#xff0c;Yuwei Qin3&#xff0c;Hubing Du 摘要: 我们提出了一种适用于一般干涉测量应用的相位展开方法。所提出的方法依赖于导数泽尼克多项式拟合&#xff08;DZPF&#xff09;技术&#xff0c;其中相…

Datawhale聪明办法学Python(task2Getting Started)

一、课程基本结构 课程开源地址&#xff1a;课程简介 - 聪明办法学 Python 第二版 章节结构&#xff1a; Chapter 0 安装 InstallationChapter 1 启航 Getting StartedChapter 2 数据类型和操作 Data Types and OperatorsChapter 3 变量与函数 Variables and FunctionsChapte…

马赛克,克星,真来了!v2.0

大家好&#xff0c;今天继续聊聊 AI 开源项目 AI 开源项目 1、DemoFusion AI 绘画的潜力还没有充分挖掘出来&#xff0c;仍然还有上升的空间。 DemoFusion 就是这么一个开源项目&#xff0c;继续深挖了 AI 绘画在高分辨率图片生成的效果。 提高分辨率&#xff0c;马赛克&a…

算法 - 二分搜索法 / 二分法(704)

原理&#xff1a; 利用数组的有序性&#xff0c;每次取查找范围的中间点&#xff0c;缩窄一半的查找空间。比较中间值和目标值的大小&#xff0c;直到找到目标值或者查找区间为空时返回。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目&…