Web自动化 —— Selenium元素定位与防踩坑

1. 基本元素定位一

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# selenium = Service("../../chromedriver.exe")
# driver = webdriver.Chrome(service=Service)
# driver.get("http://www.baidu.com")# # 使用id进行定位
# input_element = driver.find_element_by_id("kw")
# # 往输入框输入内容
# input_element.send_keys("凯学长")
# search_button = driver.find_element_by_id("su")
# # 点击搜索按钮
# search_button.click()# 隐藏正在受到自动化测试软件的控制这句话
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('excludeSwitches',['enable-automation'])
selenium = Service("../../chromedriver.exe")
driver = webdriver.Chrome(service=Service,options=chrome_options)
driver.get("http://www.baidu.com")# 以下是新的写法
input_element = driver.find_element(by=By.ID,value="kw")
input_element.send_keys("凯学长")
search_button = driver.find_element(by=By.ID,value="su")
# 点击搜索按钮
search_button.click()

2. 基本元素定位二

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# selenium = Service("../../chromedriver.exe")
# driver = webdriver.Chrome(service=Service)
# driver.get("http://www.baidu.com")# 使用id进行定位
# input_element = driver.find_element_by_id("kw")
# 往输入框输入内容
# input_element.send_keys("凯学长")
# search_button = driver.find_element_by_id("su")
# 点击搜索按钮
# search_button.click()# 隐藏正在受到自动化测试软件的控制这句话
chrome_options = webdriver.ChromeOptions()
chrome_options.add_experimental_option('excludeSwitches',['enable-automation'])
selenium = Service("../../chromedriver.exe")
driver = webdriver.Chrome(service=Service,options=chrome_options)
driver.get("http://www.baidu.com")# 以下是新的写法
# input_element = driver.find_element(by=By.ID,value="kw")
# input_element.send_keys("凯学长")
# search_button = driver.find_element(by=By.ID,value="su")
# # 点击搜索按钮
# search_button.click()# 把浏览器最大化
driver.maximize_window()driver.get("https://www.jd.com")
# jd_search_input = driver.find_element(by=By.CLASS_NAME,value="text")
# jd_search_input.send_keys("电脑")
# jd_search_button = driver.find_element(by=By.CLASS_NAME,value="button")
# jd_search_button.click()
driver.find_element(by=By.LINK_TEXT,value="家用电器").click()
# driver.find_element(by=By.LINK_TEXT,value="平板电视").click()
# 当页面以一个新的页面打开时,将会出现多个句柄(就是浏览器的页面)
# 这个时候我们需要做的事情是切换操作句柄# 句柄切换
# 拿到所有句柄
handlers = driver.window_handles
print(driver.title)
for h in handlers:if h !=driver.current_window_handle:# 切换到这个句柄上driver.switch_to.window(h)print("当前句柄是:" + driver.title)driver.find_element(by=By.PARTIAL_LINK_TEXT,value="一体").click()

3. CSS选择器定位法一

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
service = Service("../../chomedriver.exe")
driver = webdriver.Chrome(service=service)# 把浏览器最大化
driver.maximize_window()
driver.get("https://www.jd.com")
driver.find_element(by=By.CSS_SELECTOR,value="#key").send_keys("键盘")
driver.find_element(by=By.CSS_SELECTOR,value="#search > div > div.from > button").click()# css学习参考手册
# https://www.runoob.com/cssref/css-reference.html#animation

4. CSS选择器定位法二

  1. 浏览器完整的打开-关闭调用流程
from selenium import webdriver  #导入webdriver包driver=webdriver.Chrome()   #初始化一个谷歌浏览器实例
driver.maximize_window()    #最大化浏览器
driver.implicitly_wait(8)   #设置隐式时间等待driver.get("https://www.baidu.com") #通过get方法打开一个url站点driver.quit()  #关闭并退出浏览器

5. xpath定位法
1、相对路径定位
//标签名[@属性名="属性值"]

2、定位某个元素的父级元素
元素xpath/parent::"父级元素标签名"

//*[@id="list"]/dl/a/parent::dl

3、定位一组元素的第几个
xpath[数字] 注意:xpath是从1开始

例:定位第5个元素

//*[@id="list"]/dl/a[5]

4、定位到一组元素,但是需要从第n个开始
xpath[position()]

例:从第13个元素开始

//*[@id="list"]/dl/a[position()>12]

5、定位元素的属性值
xpath/@属性名

例:定位a标签的href属性值

//*[@id="list"]/dl/a/@href

6、定位标签的文本内容
xpath/text()

例:定位dd标签的文本内容

//*[@id="list"]/dl/a/dd/text()

6. 句柄切换和页面关闭操作
句柄,就是当前浏览器每个窗口的标识符,每个窗口的句柄具有唯一性,多用于页面切换与关闭指定页面;
接下来先做一个小实验,证明一下为啥需要用到句柄:
以百度新闻为例:

# -*- coding:utf-8 -*-
import time
from selenium import webdriverbrowser = webdriver.Chrome()
browser.set_window_size(1920, 1080)
browser.get("http://news.baidu.com/") #打开百度新闻页面
time.sleep(1)
handles = browser.window_handles #获取所有窗口的句柄
print("当前窗口的句柄",handles )  #这里输出所有窗口的句柄,当前只有一个窗口,所以输出的是当前窗口的句柄
browser.find_element_by_link_text("百度新闻客户端").click() #在百度新闻页面基础上(新窗口)打开百度新闻客户端页面
handles = browser.window_handles #获取所有窗口的句柄
print("全部窗口的句柄",handles ) #这里会输出两个句柄信息,以list的方式返回

 

到这里,我们怎么知道当前标记的是哪个窗口的句柄呢(就是读取哪个窗口的代码)?我们可以关闭一个窗口,如果某个窗口被关闭了,那就证明标记的是哪个窗口的句柄,在后面增加下面这行代码

browser.close() #关闭当前标识的窗口
handles = browser.window_handles #获取所有窗口的句柄
print("全部窗口的句柄",handles )

我们会发现就算打开了新的窗口,并在页面上跳转到新的窗口,但是关闭的窗口仍然是最初始的窗口,所以这就证明由始至终都是标识第一个窗口的句柄,那我们就要在进行后面一系列操作之前,先标识到新窗口的句柄

这样子,我们就可以在新窗口进行一系列的操作啦,当然,切换窗口,也可以使用重定向的方式

7. 自动化元素定位防踩坑
踩坑一:StaleElementReferenceException

selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document

异常原因: 意思是,引用的元素已过期。原因是页面刷新了,此时当然找不到之前页面的元素,就算是后退回来的页面也是不一样的。

在编写脚本时一直报这个错,使用显示等待都不行,在一顿百度操作后才知道是元素被刷新了

我们发现,仅仅是刷新了一下页面,两次的element id是不同的,这就说明这是两个不同的元素,如果用之前的element,自然会报错

原因很明显,你用别人的身份证id去找现在的人,哪怕这两个人长的很像,他也会告诉你,对不起,你找错人啦。

解决方法:

有时我们无法避免,不确定什么时候元素就会被刷新。页面刷新后重新获取元素的思路不变,这时可以使用python的异常处理语句:try…except…,异常出现时重新执行,关键代码如下

如下图:我在实际工作当中编写脚本时使用异常try捕获异常后,页面刷新后重新获取元素,可以成功找到元素了

踩坑二:ElementClickInterceptedException(元素点击交互异常)

具体报错:selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted is not clickable at point (1421, 283). Other element would receive the click:

E (Session info: chrome=104.0.5112.102)

意思是,元素定位相互覆盖,元素已经找到,但是无法点击

解决方法:

方法一:使用强制等待,但是每次都有类似的元素无法点击使用强制等待的话会延长脚本执行时间

time.sleep()

前言:之前便遇到过很多次该问题的报错,就没有管它,但是随着越来越多的元素报该错,每次使用强制等待会大大延长脚本的执行时间,于是便网上找各种方法解决该问题,最终发现是自己使用显示等待的方法错了

如下是显示等待的用法和区别

方法二:显性等待

element_to_be_clickable--元素是否可点击

vibility of element_ located--元素是否可见

presence_of_element_located--元素是否存在

如上:三种等待方法,最开始我一直使用的是presence_of_element_located,判断元素是否存在,最终还是报错,提示元素元素点击拦截异常

element_to_be_clickable--等待元素出现可以点击,便可以元素定位成功

需要先导包:

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
复制代码
element = WebDriverWait(self.browser, 5).until(EC.element_to_be_clickable((By.XPATH, "//input[@placeholder='请输入会员手机号']")))
element.clcik()
复制代码

方法三:使用JS点击

然而有时即使已经显式等待了,却仍然会报错: ElementClickInterceptedException,这多少有点奇怪,为什么 webdriver 有时就是无法点击,我不知道,也许这和他首先执行的一些验证检查有关,反正就在这一刻,它不给你点

代码如下:

element = self.browser.find_element(By.XPATH, "(//span[@class='el-checkbox__inner'])[4]")
self.browser.execute_script("arguments[0].click();", element)
复制代码

这是通过 JavaScript 完成的点击,js可以避开一些校验

👆以上便是在编写selenium自动化时元素定位时踩的坑,以此分享防止踩坑

下面是配套资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!

软件测试面试小程序

被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!

涵盖以下这些面试题板块:

1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux

6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础

 

 资料获取方式 :

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux】进程概念

文章目录 一.进程1.概念2.描述进程——pcb3.pcb(task_struct)内容分类4.查看进程(1)通过系统调用查看(2)通过ps命令查看 二.通过系统调用获取进程的PID和PPID三.通过系统调用创建子进程fork()1.fork函数创建…

锁( ReentrantLock,Synchronized)

1.lock和synchronized 语法层面 synchronized 是关键字,源码在 jvm 中,用 c 语言实现; Lock 是接口,源码由 jdk 提供,用 java 语言实现; 使用 synchronized 时,退出同步代码块锁会自动释放&…

Axure RP PC电商平台Web端交互原型模板

Axure RP PC电商平台Web端交互原型模板。原型图内容齐全,包含了用户中心、会员中心、优惠券、积分、互动社区、运营推广、内容推荐、商品展示、订单流程、订单管理、售后及服务等完整的电商体系功能架构和业务流程。 在设计尺寸方面,本套模板按照主流的…

MybatisPlus 核心功能 条件构造器 自定义SQL Service接口 静态工具

MybatisPlus 快速入门 常见注解 配置_软工菜鸡的博客-CSDN博客 2.核心功能 刚才的案例中都是以id为条件的简单CRUD,一些复杂条件的SQL语句就要用到一些更高级的功能了。 2.1.条件构造器 除了新增以外,修改、删除、查询的SQL语句都需要指定where条件。因此…

12. 微积分 - 梯度积分

Hi,大家好。我是茶桁。 上一节课,我们讲了方向导数,并且在最后留了个小尾巴,是什么呢?就是梯度。 我们再来回看一下但是的这个式子: [ f x f y

打造西南交通感知新范式,闪马智能携手首讯科技落地创新中心

9月4日,2023年中国国际智能产业博览会(以下简称“智博会”)在重庆拉开帷幕。大会期间,由上海闪马智能科技有限公司(以下简称“闪马智能”)与重庆首讯科技股份有限公司(以下简称“首讯科技”&…

Logback日志记录只在控制台输出sql,未写入日志文件【解决】

原因:持久层框架对于Log接口实现方式不一样,日记记录的位置及展示方式也也不一样 mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # sql只会打印到控制台不会输出到日志文件种mybatis-plus:configuration:log-impl…

前后端项目部署上线详细笔记

部署 参考文章:如何部署网站?来比比谁的方法多 - 哔哩哔哩大家好,我是鱼皮,不知道朋友们有没有试着部署过自己开发的网站呢?其实部署网站非常简单,而且有非常多的花样。这篇文章就给大家分享几种主流的前端…

DVWA失效的访问控制

失效的访问控制,可以认为是系统对一些功能进行了访问或权限限制,但因为种种原因,限制并没有生效,造成失效的访问控制漏洞,比如越权等 这里以DVWA为例,先访问低难度的命令执行并抓包 删除cookie,并在请求头…

从0到1学会Git(第二部分):Git的本地操作和管理

写在前面:本文介绍了在本地仓库进行文件的处理以及本地的合并等操作。 前置知识:文件可以处在三个区域,分别为工作区,暂存区和本地仓库,我们此文的目标即是将文件存储在本地仓库中。我们可以将文件的区域理解为,cpu中&#xff0c…

UDP和TCP协议报文格式详解

在初识网络原理(初识网络原理_蜡笔小心眼子!的博客-CSDN博客)这篇博客中,我们简单的了解了一下TCP/IP五层网络模型,这篇博客将详细的学习一下五层网络模型中传输层的两个著名协议:UDP和TCP 目录 一, 传输层的作用 二, UDP 1,UDP协议的特点 2,UDP报文格式 三, TC…

Python爬取天气数据并进行分析与预测

随着全球气候的不断变化,对于天气数据的获取、分析和预测显得越来越重要。本文将介绍如何使用Python编写一个简单而强大的天气数据爬虫,并结合相关库实现对历史和当前天气数据进行分析以及未来趋势预测。 1 、数据源选择 选择可靠丰富的公开API或网站作…

视频监控/视频汇聚/视频云存储EasyCVR平台接入华为ivs3800平台提示400报错,该如何解决?

开源EasyDarwin视频监控TSINGSEE青犀视频平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,在视频监控播放上,视频云存储/安防监控汇聚平台可支持1、4、9、16个画面窗口播放,可同时播放多路视频…

垃圾回收 - 复制算法

GC复制算法是Marvin L.Minsky在1963年研究出来的算法。说简单点,就是只把某个空间的活动对象复制到其它空间,把原空间里的所有对象都回收掉。这是一个大胆的想法。在此,我们将复制活动对象的原空间称为From空间,将粘贴活动对象的新…

Flink---1、概述、快速上手

1、Flink概述 1.1 Flink是什么 Flink的官网主页地址:https://flink.apache.org/ Flink的核心目标是“数据流上有状态的计算”(Stateful Computations over Data Streams)。 具体说明:Apache Flink是一个“框架和分布式处理引擎”,用于对无界…

面试总结 - 计算机网络

计算机网络 1 OSI 七层模型 | TCP与UDP | 响应状态码 OSI 模型 应用层: 计算机用户,以及各种应用程序和网络之间的接口,其功能是直接向用户提供服务,完成用户希望在网络上完成的各种工作。 HTTP SMTP FTP DNS 表示层: 负责数据格式的转换&…

算法笔记:二叉树

1 基本二叉树 二叉树是一种树形数据结构,其中每个节点最多有两个子节点,通常称为“左子节点”和“右子节点”。 二叉树的根是唯一没有父节点的节点,而所有其他节点都有一个父节点和零个或两个子节点。 1.1 基础术语 节点(Node&…

ApiPost7使用介绍 | HTTP Websocket

一、基本介绍 创建项目(团队下面可以创建多个项目节点,每个项目可以创建多个接口): 参数描述库(填写参数时自动填充描述): 新建环境(前置URL、环境变量很有用)&#x…

【GitLab私有仓库】在Linux上用Gitlab搭建自己的私有库并配置cpolar内网穿透

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具&#xf…

【搭建私人图床】使用LightPicture开源搭建图片管理系统并远程访问

文章目录 1.前言2. Lightpicture网站搭建2.1. Lightpicture下载和安装2.2. Lightpicture网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1.前言 现在的手机越来越先进,功能也越来越多,而手机…