[python][selenium] Web UI自动化8种页面元素定位方式

测试工程师必备!Selenium自动化测试全攻略 | 手写POM框架+数据驱动,轻松搞定UI自动化!


简单的加个前置知识:

第一:webdriver.Chrome()这句话,通过WebDriver的构造方法,拿到浏览器驱动的对象,然后通过这个对象,就可以调用一系列操作浏览器的方法。

因为原理就是通过浏览器驱动做桥梁实现两端通讯的。

第二:元素定位的方法find_element,是selenium中WebDriver类的方法。

find_element:返回的是单个元素对象。

find_elements:返回的是存放有多个元素对象的一个list。


定位页面元素的8种方式 (不能定位浏览器弹窗):
1、id
2、class_name
3、name
4、link_text
5、partial_link_text
6、tag_name
7、css_selector
8、XPath


我概括下:

1、2、3:元素属性,不是所有元素都有,还有可能是动态的,通常跟7、8去组合使用比较多。
4、5:是用可点击的链接的文本去定位。
6:是根据元素标签去定位。
7、8:最常用的方式,能结合前面6种方式组合去定位,我个人觉得理解后并不复杂,并且定位准确。
用什么定位方式,需要根据实际情况去选择,才是最合适的,

注意:大家应该都知道网页F12的开发者工具里右键复制,虽然快捷,但在复杂的页面并不好用,不准确,有时生成的值还很长看着臃肿。
   我发现右键复制生成的路径,根节点都是用 id,所以 id 动态的话就只能手写定位了。

下面我用百度搜索来做demo,直接用代码+注释演示说明。


1、id

元素的id属性定位,id在当前页面是唯一的,但不是所有元素都有,有些页面值是动态的

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:输入框输入"日历",点击搜索
driver.find_element(By.ID, "kw").send_keys("日历")
driver.find_element(By.ID, "su").click()
sleep(3)
driver.quit()

2、class_name

元素的class属性定位,大部分都有,但也有些没有,有些页面值是动态的

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:输入框输入"日历",点击搜索,点开年份下拉列表,把年份选择1903年
driver.find_element(By.CLASS_NAME, "s_ipt").send_keys("日历")
# 注意这里:有不少元素有多个class,它们之间会用空格隔开,但是代码里不能用空格,有两种方式
# 方法一:用.代替,比如:百度的这个搜索按钮"bg s_btn",写成"bg.s_btn"
driver.find_element(By.CLASS_NAME, "bg.s_btn").click()
sleep(2)
# 方法二:使用最后一个class,比如:年份下拉列表的class是:sc-icon cu-icon _toggle-icon_9e3yq_71 toggle-icon_1tMxP,用最后一个
driver.find_element(By.CLASS_NAME, "toggle-icon_1tMxP").click()
# 年份class是"_selectItem_9e3yq_23 ",用网页F12检查有152个,要拿到想要的数据:
# 1:在网页F12的elements窗口搜索查找到数据位于152条中的哪个位置,找到后回到代码里用find_elements方法直接加索引获取
# 2:用下面的方法,用elements获取所有年份数据再用if判断我要的年份
elms = driver.find_elements(By.CLASS_NAME, "_selectItem_9e3yq_23 ")
# 先判断列表是否为空,因为有时候卡顿或者加载慢是可能导致获取元素失败的
if elms:
for e in elms:
if e.text == "1903年":
e.click()
break
# 这里做了点击操作后一定要结束循环,不然会报异常StaleElementReferenceException。
# 通过反复尝试和根据代码流程看,大致就是你循环过程中操作了元素,但是还继续循环操作就有可能因为元素发生变化找不到了,
# 因为这里是点开下拉列表然后F12源码才会显示出年份元素,做了点击操作后下拉列表就会隐藏,然后元素也没了,操作自然报错。
# 奇怪的是正常跑没问题,我自己把for、if、click3行打断点debug去看,跑到click就怎样都会出异常,手速点再快也不行。
# 有大佬懂的话,不介意可以评论区指导下在下。
sleep(3)
driver.quit()

3、name

元素的name属性定位,也是不是所有都有,有些页面值是动态的

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:输入框输入"日历"
driver.find_element(By.NAME, "wd").send_keys("日历")
sleep(3)
driver.quit()

4、link_text

根据可点击的链接的文本去定位

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:点击页面上的"关于百度"和"更多"
driver.find_element(By.LINK_TEXT, "关于百度").click()
driver.find_element(By.LINK_TEXT, "更多").click()
sleep(3)
driver.quit()

5、partial_link_text

也是根据可点击的链接的文本去定位,但这是文本的模糊匹配,只要包含有关键字就可以匹配

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:点击页面上的"关于百度"和"更多"
driver.find_element(By.PARTIAL_LINK_TEXT, "于百").click()
driver.find_element(By.PARTIAL_LINK_TEXT, "更").click()
sleep(3)
driver.quit()

6、tag_name

根据元素标签名定位

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 操作:输入框输入"日历"
elem = driver.find_elements(By.TAG_NAME, "input")
for e in elem:
if e.get_attribute("name") == "wd":
e.send_keys("日历")
sleep(3)
driver.quit()

7、css_selector

根据css选择器定位元素

7.1 常用属性

 
from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 一:先看常用的属性格式写法,下面操作:输入“日历”,点击搜索,等待3秒,在日历上点击上个月,输入"1993"
# 1、html标签:页面上一般都有多个相同标签,所以需要再加上父级标签指明是哪个标签下的,父级标签也有多个就再往上找父级,如此类推
driver.find_element(By.CSS_SELECTOR, "span>input").send_keys("日")
# 2、name:[属性名],例:[name='wd']
driver.find_element(By.CSS_SELECTOR, "[name='wd']").send_keys("历")
# 3、id:#id,例:#su
driver.find_element(By.CSS_SELECTOR, "#su").click()
sleep(3)
# 4、class:.class,例:".calendar-prev-month_mlSD9 OP_LOG_BTN"
driver.find_element(By.CSS_SELECTOR, ".calendar-prev-month_mlSD9.OP_LOG_BTN").click()
# 5、组合使用:用标签+属性,下面是 input标签 + class_name + name的组合
driver.find_element(By.CSS_SELECTOR, "input.s_ipt[name='wd']").send_keys("1993")
sleep(3)
driver.quit()

7.2 模糊匹配定位

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 二:模糊匹配
# 这次用a标签和href属性来试,打开百度贴吧,下面代码一共会打开6个百度贴吧页面
driver.find_element(By.CSS_SELECTOR, "a[href='http://tieba.baidu.com/']").click()
# 1、模糊匹配-包含,只给出值的中间部分,可以匹配到开头和结尾
driver.find_element(By.CSS_SELECTOR, "a[href*='tieba.bai']").click()
# 2、模糊匹配-匹配开头,只给出值的开头部分内容,可以匹配到后面
driver.find_element(By.CSS_SELECTOR, "a[href^='http://tie']").click()
# 3、模糊匹配-匹配结尾,只给出值的后面结尾内容,可以匹配到前面
driver.find_element(By.CSS_SELECTOR, "a[href$='ba.baidu.com/']").click()
# 4、模糊匹配-标签,只给出值,可以匹配到标签
driver.find_element(By.CSS_SELECTOR, "*[href='http://tieba.baidu.com/']").click()
# 娱乐一下,超级模糊。。
driver.find_element(By.CSS_SELECTOR, "*[href*='tieba']").click()
sleep(3)
driver.quit()

7.3 通过父元素定位子元素的方法

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 三、通过父元素定位子元素的方法,这里用百度首页左上角的一堆链接演示
# 1、定位某标签下的第一个子元素::first-child,例:a:first-child,下面定位点击的是新闻
driver.find_element(By.CSS_SELECTOR, "div#s-top-left>a:first-child").click()
# 2、定位某标签下的指定位置的子元素::nth-child(n),例:a:nth-child(5),下面定位点击的是视频
driver.find_element(By.CSS_SELECTOR, "div#s-top-left>a:nth-child(5)").click()
# 还是定位点击视频,用elements拿到所有子元素,再用索引去获取元素,结果也是一样
driver.find_elements(By.CSS_SELECTOR, "div#s-top-left>a")[4].click()
# 3、定位某标签下的最后一个子元素::last-child,例:a:last-child
# 注意:last-child它是只匹配父元素下的所有元素的最后一个子元素,如果最后一个子元素不是你要的那个标签类型,那这个方法就没用了
# 比如:现在演示的百度这里,在<div>下,第1个<a>新闻,第2个<a>hao123,第3个<a>地图,最后一个标签不是<a>,是<div>;那就不能用a:last-child定位到,但是可以用div:last-child定位到
# 结论:父元素下最后一个标签是 x 就 x:last-child。可以在百度首页,用网页F12在Elements窗口,把那个<div>删除或者移到其他位置去试试
driver.find_element(By.CSS_SELECTOR, "div#s-top-left>div:last-child").click()
sleep(3)
driver.quit()

8、XPath

根据元素路径定位,css方式看完后,看XPath应该就很好理解了,这里暂时列举出常用的

8.1 路径

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 一:路径
# 路径写法,相对路径://
driver.find_element(By.XPATH, "//span/input").send_keys("日历")
# 路径写法,绝对路径:/
driver.find_element(By.XPATH, "/html/body/div/div/div[5]/div/div/form/span/input").send_keys("日历")
sleep(3)
driver.quit()

8.2 属性

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 二:属性
# 根据属性id、name、class定位,注意:class定位,class值有多个时,值需要全部填写
# 格式://标签名[@属性名='属性值']
driver.find_element(By.XPATH, "//input[@id='kw']").send_keys("日")
driver.find_element(By.XPATH, "//input[@name='wd']").send_keys("历")
driver.find_element(By.XPATH, "//input[@class='bg s_btn']").click()
# 多个属性定位
driver.find_element(By.XPATH, "//input[@name='wd' and @class='s_ipt']").send_keys("日历")
sleep(3)
driver.quit()

8.3 其他

from selenium import webdriver
from selenium.webdriver.common.by import By
from time import sleep
driver = webdriver.Chrome()
driver.maximize_window()
driver.implicitly_wait(10)
driver.get("https://www.baidu.com")
# 三:其他
# 匹配标签内的文本
driver.find_element(By.XPATH, "//a[text()='新闻']").click()
# 模糊匹配标签内的文本
driver.find_element(By.XPATH, "//a[contains(text(),'新')]").click()
# 指定标签内的属性匹配标签,例:百度首页点击贴吧
driver.find_element(By.XPATH, "//*[@href='http://tieba.baidu.com/']").click()
# 使用索引定位第几个标签,例:百度首页点击贴吧
driver.find_element(By.XPATH, '//div[@id="s-top-left"]/a[4]').click()
sleep(3)
driver.quit()

测试工程师必备!Selenium自动化测试全攻略 | 手写POM框架+数据驱动,轻松搞定UI自动化!

 

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

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

相关文章

丝杆支撑座在电子装配中的关键作用

丝杆支撑座是电子装配过程中不可或缺的组件&#xff0c;主要用于支撑和固定丝杆&#xff0c;确保其稳定性和精度。在高速、高精度装配场景中&#xff0c;丝杆支撑座的作用尤为突出。稳定性与精度保障&#xff1a;丝杆支撑座采用高品质钢材制作&#xff0c;具有高刚性和高强度&a…

微信小程序页面间通信的实现方式

微信小程序中页面间的通信是指不同页面之间的数据传递、状态同步或交互操作&#xff0c;常见于多页面协作场景。根据通信方向和场景不同&#xff0c;主要有以下几种实现方式&#xff1a;一、基于页面跳转的参数传递1. 正向传递&#xff08;A页面到B页面&#xff09;通过URL参数…

uniapp开发微信小程序(新旧版本对比:授权手机号登录、授权头像和昵称)

目录标题授权手机号新旧版本核心差异对比强制使用新版的情况代码实现方案特殊处理逻辑企业账号要求最佳实践建议授权头像和昵称新旧版本核心差异对比强制使用新版的情况代码实现方案最佳实践建议注意事项授权手机号 新旧版本核心差异对比 触发方式 旧版&#xff08;2023年前&…

Java函数式编程之【Stream终止操作】【下】【三】【收集操作collect()与分组分区】【下游收集器】

分组收集器groupingBy()&#xff1a;groupingBy()收集器用于按条件对元素象进行分组&#xff0c;并将结果存储在Map实例中。其作用与数据库的SQL语句的group by的用法有异曲同工之妙。 分区收集器partitioningBy()&#xff1a;partitioningBy()可以看作是分组groupingBy()的特殊…

python设计模式-工厂模式

工厂模式的核心思想&#xff1a;封装对象创建过程、解耦对象使用与创建 。示例代码&#xff1a;from enum import Enum# 基类&#xff1a;人类 class Person:species Homo sapiensdef __init__(self, name):self.name namedef __str__(self):return f"{self.__class__._…

Rust:anyhow::Result 与其他 Result 类型转换

当函数返回的不是 anyhow::Result 而是其他 Result 类型时&#xff08;如 std::io::Result、serde_json::Result 或自定义 Result&#xff09;&#xff0c;可通过以下方法统一处理错误类型&#xff0c;确保与 anyhow 兼容或实现错误传播&#xff1a;&#x1f6e0;️ 一、错误类…

PLC-梯形图编程

1.位运算,比较 如&#xff1a;>,<,, 2.定时器 生成脉冲TP&#xff0c;常开触点闭合触发&#xff0c;赋值10秒时长&#xff0c;PT配置参数&#xff0c;ET运行时已PT计时 接通延时TON&#xff0c;常开触点闭合触发&#xff0c;延时10秒后赋值 关断延时TOF&#xff0c;常开触…

LLM学习笔记5——InstructGPT

系列文章目录 参考文献 参考文献 参考文献 参考视频 文章目录系列文章目录前言目前大模型不同的技术流派与框架路线&#xff1a;1. ​​BERT&#xff1a;Encoder-only架构​​​​1&#xff09; 架构特点​​​​2&#xff09; 训练目标​​3&#xff09; ​​​​应用场景2. …

热能小车cad【12张】三维图+设计说明书

摘要 无碳小车来自全国大学生工程能力训练大赛题目&#xff0c;根据“节能减排&#xff0c;绿色出行”的环保理念&#xff0c;提出了一种基于热力驱动的具有方向自动控制的无碳小车。 本文设计的无碳小车主要是将热能转化成机械能&#xff0c;用来驱动小车前进的装置&#xff0…

云原生 DevOps 实战之Jenkins+Gitee+Harbor+Kubernetes 构建自动化部署体系

技术背景​ 在云原生生态中&#xff0c;工具链的选择直接决定 CI/CD 流水线的效率与稳定性。本次方案的工具组合并非偶然&#xff0c;而是基于各组件的核心优势与生态适配性&#xff1a;​ 代码管理层&#xff1a;Gitee 作为国内主流的代码托管平台&#xff0c;支持 Git 分布…

二建机电工程专业都考哪些知识点?

二建机电工程专业需要考《建设工程施工管理》《建设工程法规及相关知识》和《机电工程管理与实务》三个科目。其中《机电工程管理与实务》是专业科目&#xff0c;也是考试重点&#xff0c;主要考查机电工程技术、机电工程相关法规与标准、机电工程项目管理实务等内容。具体如下…

React + ts + react-webcam + CamSplitter 实现虚拟摄像头解决win摄像头独占的问题

一、安装 CamSplitter 这块网上有很多教程了&#xff0c;这里不再赘述&#xff0c;就一点&#xff0c;需要分几个虚拟摄像头&#xff0c;就要在CamSplitter 的安装目录下 driver_install.cmd 执行几次。二、React ts react-webcam 调用虚拟摄像头import { useState, useEffec…

【深度学习①】 | Numpy数组篇

0 序言 本文为NumPy数组库的系统学习笔记&#xff0c;将自己先前的笔记做一个总结归纳。内容涵盖数组基础、创建、索引、变形、运算、函数、布尔型数组及与张量的衔接等内容。通过具体示例解析核心概念与操作&#xff0c;帮助读者掌握NumPy的使用逻辑与方法&#xff0c;为后续深…

5.实现 call

call 是 JavaScript 中非常核心的函数方法之一。它能改变函数的执行上下文&#xff08;也就是 this 的指向&#xff09;&#xff0c;在日常开发和面试中都极其常见。本文将带你一步步实现一个 Function.prototype.call 的自定义版本&#xff0c;真正理解它的底层原理。✨ 一、c…

Go语言中的盲点:竞态检测和互斥锁的错觉

&#x1f9e0; Go语言中的盲点&#xff1a;竞态检测和互斥锁的错觉 使用 -race 就能发现所有并发问题&#xff1f;加了 mutex 就万无一失&#xff1f; 这篇文章揭示了 Go 并发编程中的一个“危险盲区” —— 互斥锁并不能总能保护你免受数据竞争的影响&#xff0c;尤其是在 -ra…

从文件到文件描述符:理解程序与文件的交互本质

一、理解文件 抛一个概念&#xff1a; 文件 内容 属性。 1. 那么&#xff0c;空文件有大小吗&#xff1f;答案是有的。因为空文件指的是文件内容为空&#xff0c;文件属性也要占据大小啊。 将来对文件操作&#xff0c;无非分为两类&#xff1a; 1.对文件内容做修改。 2.对文件…

优化算法专栏——阅读导引

前言 提醒&#xff1a; 文章内容为方便作者自己后日复习与查阅而进行的书写与发布&#xff0c;其中引用内容都会使用链接表明出处&#xff08;如有侵权问题&#xff0c;请及时联系&#xff09;。 其中内容多为一次书写&#xff0c;缺少检查与订正&#xff0c;如有问题或其他拓展…

[ The Missing Semester of Your CS Education ] 学习笔记 Vim篇

“Writing English words and writing code are very different activities. When programming, you spend more time switching files, reading, navigating, and editing code compared to writing a long stream.” —— < The Missing Semester of Your CS Education &g…

Linux 系统中定时执行指定命令 crontab 定时任务配置

crontab 定时任务配置是 Linux/Unix 系统中用于自动、周期性执行指定命令或脚本的工具&#xff0c;相当于系统的 “定时闹钟”。它可以让系统在预设的时间&#xff08;如每天凌晨、每周一、每月 1 号等&#xff09;自动完成重复性工作&#xff0c;无需人工干预。自动化运维定期…

[ Leetcode ]---快乐数

题目链接 Leetcode快乐数 题目描述 如下图&#xff1a; 题目解析&#xff1a; 1.双指针法 算法核心思路 判断快乐数的关键挑战是如何检测是否进入无限循环。这里使用了快慢指针法&#xff08;Floyd 循环检测算法&#xff09;&#xff0c;这是一种高效检测循环的技巧&#…