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的技巧有哪些?通过这些问题的答案,可以帮助您更好的利用文件转换…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解
突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 安全措施依赖问题 GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...
