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选择器定位法二
- 浏览器完整的打开-关闭调用流程
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、计算机基础

资料获取方式 :

相关文章:
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(serviceService) # driver.…...
【数据结构】树和二叉树的概念及结构(一)
目录 一,树的概念及结构 1,树的定义 2,树结点的分类及关系 3,树的表示 二,二叉树的概念及结构 1,二叉树的定义 2,特殊的二叉树 3,二叉树的性质 4,二叉树的存储结构 1&…...
第三章 USB应用笔记之USB鼠标(以STM32 hal库为例)
第三章 USB应用笔记之USB鼠标(以STM32 hal库为例) 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 第三章 USB应用笔记之USB鼠标(以STM32 hal库为例)前言一、STM32 U…...
微服务01-基本介绍+注册中心EureKa
基本介绍 服务集群:一个请求由多个服务完成,服务接口暴露,以便于相互调用; 注册中心:每个服务的状态,需要进行维护,我们可以在注册中心进行监控维护服务; 配置中心:这些…...
【ES6】JavaScript中的异步编程:async和await
在JavaScript中,异步编程是一种处理长时间运行的操作的方法,这些操作包括读取文件、网络请求或处理大数据等。在传统的回调函数中,代码按照顺序执行,一旦遇到长时间运行的操作,就需要回调函数来处理结果。这使得代码变…...
51单片机热水器温度控制系统仿真设计( proteus仿真+程序+原理图+报告+讲解视频)
51单片机热水器温度控制系统仿真设计 1.主要功能:2.仿真3. 程序代码4. 原理图5. 设计报告6. 设计资料内容清单 &&下载链接 51单片机热水器温度控制系统仿真设计( proteus仿真程序原理图报告讲解视频) 仿真图proteus7.8及以上 程序编译器&#x…...
Spring Boot 配置文件加密
方式一:Spring Cloud Config 一、建立config server 1. build.gradle 文件中添加: plugins {id javaid org.springframework.boot version 2.7.0id io.spring.dependency-management version 1.0.11.RELEASE }ext {set(springCloudVersion, "202…...
【树形权限】树形列表权限互斥选择、el-tree设置禁用等等
需求:按照权限管理配置的数据权限树展开;点击查看按钮后进入其他指定机构选择弹窗为一树形结构 本文章对项目中出现得关键点进行总结。 一、实现如上树形列表 在 element 官方表格示例中,实现树形表格列表数据渲染,非常简单。只…...
ubuntu 22.04安装cuda、cudnn、conda、pytorch
1、cuda 视频连接 https://www.bilibili.com/video/BV1bW4y197Mo/?spm_id_from333.999.0.0&vd_source3b42b36e44d271f58e90f86679d77db7cuda 11.8 https://developer.nvidia.com/cuda-toolkit-archive点击进入 https://developer.nvidia.com/cuda-11-8-0-download-arc…...
2023 最新前端面试题 (HTML 篇)
1. src 和 href 的区别 src 用于替换当前元素(引入),href 用于在当前文档和引用资源之间确立联系(引用) (1)src(source) 指向外部资源的位置,指向的内容将会嵌…...
华为云银河麒麟V10安装libmcrypt
本次安装是在华为云上执行。cpu是鲲鹏,操作系统是银河麒麟V10. 先下载安装包: wget http://downloads.sourceforge.net/mcrypt/libmcrypt-2.5.8.tar.gz 解包,进入目录中。 执行如下命令: ./configure make make install 执…...
智慧导览|智能导游系统|AR景区导览系统|景区电子导览
随着文旅市场的加快复苏,以及元宇宙、VR、AR、虚拟数字人等新兴技术的快速发展,文旅行业也正在加快数字化转型的步伐,向智慧景区建设迈进。为满足不同年龄段游客的游览需要,提升旅游服务体验,越来越多的旅游景区、博物…...
【Docker】Docker基本使用介绍
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。 一、安装Docker 首先,你需要从官方网站上下载Docker的安装包,并按…...
Linux命令200例:man用于显示和阅读关于Linux内置命令的使用说明
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师࿰…...
idea 无法识别maven的解决
问题描述 从git拉取代码或者修改文件夹以后,整个项目所有依赖爆红无法通过修改或者重新加载maven解决版本为idea 2021 问题定位 maven的版本太高,而idea的般本太低,导致识别的时候稳定性差 解决 使用idea原生的maven版本 选择已捆绑的m…...
String底层函数的实现方式
一、常见的String封装函数 1. strcpy函数的实现 char *strcpy(char *dest, const char *src) {char *tmp dest;while ((*dest *src) ! \0)/* nothing */;return tmp; } 2. strncpy函数的实现 char *strncpy(char *dest, const char *src, size_t count) {char *tmp dest…...
uniapp实现微信小程序全局可分享功能
uniapp实现微信小程序全局【发送给朋友】、【分享到朋友圈】、【复制链接】 主要使用 Vue.js 的 全局混入 1.创建一个全局分享的js文件。示例文件路径为:./utils/shareWx.js ,在该文件中定义全局分享的内容: export default {data() {retur…...
大数据成为市场营销利器 ,促进金融贷款企业获客精准化
随着大数据技术的不断普及,中国对尖端技术和云计算技术的投资大幅增加。大数据、云计算技术、物联网等一系列新一代信息技术也加速完善。 目前,大数据技术也非常成熟,大数据的应用领域也多种多样。大数据的重要方面“运营商大数据”已经被政…...
Acwing 3472. 八皇后
题目如下: 会下国际象棋的人都很清楚:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。 如何将 88 个皇后放在棋盘上(有 88 个方格),使它们谁也不能被吃掉! 这就是著名的八皇后问题。 对于某个满足要…...
Word转为PDF后图片模糊怎么办?Word转为PDF的技巧介绍
将Word文档转为PDF是我们日常办公和文档处理中常见的需求。PDF格式的优势在于跨平台兼容性、保留原始格式、文档保护以及方便共享和分发等方面。本文将探讨Word转为PDF后图片模糊怎么办?Word转为PDF的技巧有哪些?通过这些问题的答案,可以帮助您更好的利用文件转换…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
