[python][selenium] Web UI自动化8种页面元素定位方式
简单的加个前置知识:
第一: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"
# html标签:页面上一般都有多个相同标签,所以需要再加上父级标签指明是哪个标签下的,父级标签也有多个就再往上找父级,如此类推
driver.find_element(By.CSS_SELECTOR, "span>input").send_keys("日")
# name:[属性名],例:[name='wd']
driver.find_element(By.CSS_SELECTOR, "[name='wd']").send_keys("历")
# id:#id,例:#su
driver.find_element(By.CSS_SELECTOR, "#su").click()
sleep(3)
# class:.class,例:".calendar-prev-month_mlSD9 OP_LOG_BTN"
driver.find_element(By.CSS_SELECTOR, ".calendar-prev-month_mlSD9.OP_LOG_BTN").click()
# 组合使用:用标签+属性,下面是 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()
# 模糊匹配-包含,只给出值的中间部分,可以匹配到开头和结尾
driver.find_element(By.CSS_SELECTOR, "a[href*='tieba.bai']").click()
# 模糊匹配-匹配开头,只给出值的开头部分内容,可以匹配到后面
driver.find_element(By.CSS_SELECTOR, "a[href^='http://tie']").click()
# 模糊匹配-匹配结尾,只给出值的后面结尾内容,可以匹配到前面
driver.find_element(By.CSS_SELECTOR, "a[href$='ba.baidu.com/']").click()
# 模糊匹配-标签,只给出值,可以匹配到标签
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")
# 三、通过父元素定位子元素的方法,这里用百度首页左上角的一堆链接演示
# 定位某标签下的第一个子元素::first-child,例:a:first-child,下面定位点击的是新闻
driver.find_element(By.CSS_SELECTOR, "div#s-top-left>a:first-child").click()
# 定位某标签下的指定位置的子元素::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()
# 定位某标签下的最后一个子元素::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()
[python][selenium] Web UI自动化8种页面元素定位方式的更多相关文章
- Python+Selenium - Web自动化测试(二):元素定位
前言 前面已经把环境搭建好了,现在开始使用 Selenium 中的 Webdriver 框架编写自动化代码脚本,我们常见的在浏览器中的操作都会有相对应的类方法,这些方法需要定位才能操作元素,不同网页的 ...
- Python selenium web UI之Chrome 与 Chromedriver对应版本映射表及下载地址和配置(windows, Mac OS)
浏览器及驱动下载 进行web UI 自动化时,需要安装浏览器驱动webdriver,Chrome浏览器需要安装chromedriver.exe 驱动,Firefox需安装 geckodriver.ex ...
- python+selenium封装UI自动化框架
seleinum框架 框架的思想: 解决我们测试过程中的问题:大量的重复步骤,用自动化来实现 1)配置和程序的分离 2)测试数据和程序的分离 3)不懂编程的人员可以方便使用:使用的 ...
- 基于PO和单例设计模式用python+selenium进行ui自动化框架设计
一)框架目录的结构 二)config包当中的config.ini文件主要是用来存项目的绝对路径,是为了后续跑用例和生成测试报告做准备然后目前的配置文件大都会用yaml,ini,excel,还有.py也 ...
- 【python+selenium的web自动化】- 8种元素定位方式详解
我们在做WEB自动化时,最根本的就是操作页面上的各种元素,而操作的基础便是元素的定位,只有准确地定位到唯一元素才能进行后续的自动化控制,下面将对各种元素定位方式进行总结归纳. 说明:以下操作统 ...
- selenium(12)-web UI自动化项目实战(PO模式,代码封装)
web UI自动化项目实战-项目 项目使用禅道,所以你需要搭建1个禅道,搭建禅道的方法和步骤见 https://www.cnblogs.com/xinhua19/p/13151296.html 搭建U ...
- Python+Selenium爬取动态加载页面(2)
注: 上一篇<Python+Selenium爬取动态加载页面(1)>讲了基本地如何获取动态页面的数据,这里再讲一个稍微复杂一点的数据获取全国水雨情网.数据的获取过程跟人手动获取过程类似,所 ...
- Python+Selenium爬取动态加载页面(1)
注: 最近有一小任务,需要收集水质和水雨信息,找了两个网站:国家地表水水质自动监测实时数据发布系统和全国水雨情网.由于这两个网站的数据都是动态加载出来的,所以我用了Selenium来完成我的数据获取. ...
- python+selenium基础篇,三种等待方式,显示、隐式、强制等待
1.显示等待: from selenium import webdriver from time import sleep from selenium.webdriver.support.ui imp ...
- Python3.x:Selenium中的webdriver进行页面元素定位
Python3.x:Selenium中的webdriver进行页面元素定位 页面上的元素就像人一样,有各种属性,比如元素名字,元素id,元素属性(class属性,name属性)等等.webdriver ...
随机推荐
- Libgdx游戏开发(7)——开始游戏界面实现
原文: Libgdx游戏开发(7)--开始游戏界面实现-Stars-One的杂货小窝 上篇文章也是讲解了如何实现暂停,但实际上,上篇的做法可能不够优雅 因为暂停和游戏界面我们可以分成2个Screen对 ...
- 委托之Action与Func
1 例程代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- 基于Java+SpringBoot+vue+element助农平台设计和实现
\n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自 ...
- [oeasy]python005_退出游乐场_重启游乐场_系统态shell_应用态_quit
退出终端_重启游乐场_shell_quit Python 回忆 上次 了解了 python 进入了 python 游乐场 在游乐场 可以做 简单的计算 还可以做 乘方运算 数字特别大之后 游乐 ...
- oeasy教您玩转vim - 34 - # 查找进阶
查找进阶 回忆上节课内容 上次是搜索,是全文搜索 和我们以前的行内有点像 / 正向,? 反向 n 保持方向,N 改变方向 hls 让搜索结果高亮 wrapscan 可以从头搜索 noh 取消本次高 ...
- EasyDesktop 浏览器书签管理从未如此简单
作为一名软件开发从业人员, 每天80%的时间都在与浏览器打交道, 一半的时间在用浏览器开发调试, 另一半时间则是在互联网上搜寻各种知识和资源. 为此, 我的浏览器书签栏存储和很多非常棒的链接, 多到2 ...
- SUM-ACM——VJ天梯训练赛
这次比赛我暴露了很多问题,一些模拟还有贪心思路错误. 补题如下: E - E 题解:一道模拟题,我的问题在于不知道怎么替换下一个,就从0开始遍历数组然后数组的值--,如果为零就continue下一个, ...
- 题解:P7482 不条理狂诗曲
题解:P7482 不条理狂诗曲 本题解借鉴 blossom_j 大佬思路,但这位大佬的题解似乎没放正确代码. 题意 对于每一个 \(a\) 的子区间 \(a_{l\dots r}\),求选择若干个不连 ...
- 30FPS和120FPS在游戏中的区别
30FPS和120FPS的区别: 从动画上,时间尺度更小,渲染的时候物体单帧移动距离更小从物理引擎计算上,每一次的迭代更细致,计算更精确从渲染上:从触摸事件上,响应更及时,从触摸到屏幕,到系统捕捉,到 ...
- 查询当前网段的所有在用IP
查询当前网段的所有在用IP For /L %i in (0,1,254) DO ping 192.168.10.%i >>D:\IP.txt https://www.cnblogs.com ...