selenium(一)基于java、元素定位

Selenium自动化

Selenium是一个用于Web应用程序的自动化测试工具。它直接运行在浏览器中,可以模拟用户在浏览器上面的行为操作。

chrome下载

https://www.google.com/chrome/ 

下载的结果是 “ChromeSetup.exe”,双击该文件,安装程序会自动启动。

默认安装位置:C:\Program Files\Google\Chrome\Application\chrome.exe

结果我的在:C:\Users\91073\AppData\Local\Google\Chrome\Application\chrome.exe

。。。为啥?


下载驱动

最新版:Chrome for Testing availability

查看谷歌浏览器版本

谷歌浏览器输入网址的地方输入:chrome://version

下载与浏览器对应(或相近)版本的浏览器驱动:http://chromedriver.storage.googleapis.com/index.html

 备用地址:CNPM Binaries Mirror

解压后得到一个chromedriver.exe驱动文件


禁用自动升级

关闭自动升级方法:

1.右键单击【计算机】——【管理】——【计算机管理本地】——【系统工具】——【任务计划程序】——【任务计划程序库】——这里找到两个和Google自动更新相关的任务计划【GoogleUpdateTaskMachineCore】与【GoogleUpdateTaskMachineUA】,把这两个选项禁用。

2.在【服务和应用程序】——【服务】,这里找到了两个和Google更新相关的服务【Google更新服务(gupdate)】、【Google更新服务(gupdatem)】,右键——选择属性——启动类型禁用即可;


卸载谷歌浏览器

在卸载当前版本之前,建议备份你的书签、扩展、密码等资料。

  1. 通过Windows + R快捷键调出“运行”对话框。
  2. 键入APPWIZ.CPL和命中输入。

这将带您到所有已安装应用程序的列表。从列表中选择Google Chrome,然后点击卸载 命令。


降级版本

版本报错

Caused by: org.openqa.selenium.SessionNotCreatedException: session not created: This version of ChromeDriver only supports Chrome version 114
Current browser version is 116.0.5845.97 with binary path C:\Users\91073\AppData\Local\Google\Chrome\Application\chrome.exe

Google浏览器历史版本下载地址

Download older versions of Google Chrome for Windows, Linux and Mac

按住alt键,双击桌面的谷歌浏览器桌面图标

拷贝目标路径:C:\Users\lenovo\AppData\Local\Google\Chrome\Application\chrome.exe

打开命令提示符,输入如下并回车键;

cd C:\Users\lenovo\AppData\Local\Google\Chrome\Application

输入“chrome.exe--disable-remote-words-auto-upgrade--version=版本号”,然后按回车键。在这里,请将“版本号”替换为所需的版本号。


Selenium入门

maven坐标

打开selenium的仓库地址 :https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java

直接拷贝到pom文件吧,,

<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.5</version>
</dependency><!-- 测试工具testng-->
<dependency><groupId>org.testng</groupId><artifactId>testng</artifactId><version>6.14.3</version><scope>test</scope>
</dependency>

入门案例

如果浏览器驱动未加入环境变量,那么创建浏览器驱动的时候,需要指定浏览器驱动的路径

public class Client {public static void main(String[] args) throws InterruptedException {//配置浏览器驱动地址System.setProperty("webdriver.chrome.driver", "D:\\tools\\chrome\\driver113\\chromedriver.exe");//打开Chrome浏览器WebDriver webDriver = new ChromeDriver();TimeUnit.SECONDS.sleep(5);//打开百度网站webDriver.get("https://www.baidu.com");TimeUnit.SECONDS.sleep(2);//输入框输入搜索关键词 selenium 中文官网webDriver.findElement(By.id("kw")).sendKeys("selenium 中文官网");TimeUnit.SECONDS.sleep(2);//点击百度一下按钮webDriver.findElement(By.id("su")).submit();TimeUnit.SECONDS.sleep(2);//查询所有搜索的结果List<WebElement> resultElements = webDriver.findElements(By.className("result"));if (!resultElements.isEmpty()) {//找到第一条结果的第一个链接List<WebElement> aTagElements = resultElements.get(0).findElements(By.tagName("a"));if (!aTagElements.isEmpty()) {//新开一个窗口打开此链接String href = aTagElements.get(0).getAttribute("href");System.out.println(href);((JavascriptExecutor) webDriver).executeScript(String.format("window.open('%s')", href));}}TimeUnit.SECONDS.sleep(10);//关闭浏览器webDriver.quit();}
}

结果,很神奇的哦


命令行打开浏览器

new ChromeDriver(options);

如果希望Chrome 浏览器启动时附带启动参数,可通过addArguments 方式加载。

希望测试某个浏览器插件,可通过addExtensions方式提前加载以.crx 为扩展名的插件

感觉上和addArguments有点类似,不过setExperimentalOption是设置实验选项ChromeDriver选项尚未通过ChromeOptions API公开),这个方法我比较经常用来设置浏览器默认下载路径

对于一台机器上安装了多个版本的Chrome浏览器,可以使用setBinary 指定待测试Chrome。

让 selenium 连接我们手动打开的浏览器

打开浏览器有两种方式:图标点击和命令行运行。

图标点击不用多说,我们经常使用这种方式打开浏览器。命令行方式允许我啰嗦一句,找到浏览器的安装目录,在安装目录中输入 chrome.exe 就可以了。 比如我的 chrome 浏览器安装在

C:\Users\91073\AppData\Local\Google\Chrome\Application

这个路径,则在这个目录下打开 cmd 命令行,输入 chrome.exe,就可以打开一个浏览器

在浏览器打开的时候设置额外的参数,为它提供不同的功能。 通过 selenium 连接浏览器,需要用到两个参数 --remote-debugging-port 和 --user-data-dir

  • --remote-debugging-port 这个参数允许我们通过远程的方式连接,selenium 当然也可以。
  • --user-data-dir 这个参数指定一个独立的目录存放产生的用户数据,在连接时也要设置,否则会失效。
chrome.exe --remote-debugging-port=9222 --user-data-dir="F:\selenium\ChromeProfile"

有了远程调试地址,selenium 连接浏览器就变的很简单,只需要加 2 行代码。 创建一个选项,绑定debuggerAddress 远程调试地址。 此时就可以用 selenium 控制之前手工打开的浏览器了。

            //配置浏览器驱动地址System.setProperty("webdriver.chrome.driver", "F:\\webrpaTest\\RPA\\RoboticProcessAutomation\\browser\\driver\\chrome\\121\\chromedriver.exe");ChromeOptions options = new ChromeOptions();options.setBinary("C:\\Users\\91073\\AppData\\Local\\Google\\Chrome\\Application\\chrome.exe");//设置 Chrome 的远程调试端口地址options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
//            WebDriver driver = new ChromeDriver(ChromeDriverService.createDefaultService(), options);WebDriver driver = new ChromeDriver(options);System.out.println(driver.getTitle());

WebDriver 实例化参数

Chome浏览器部分

executable_path:浏览器驱动程序路径,如果没有制定,则默认使用环境变量PATH中设置的路径

options:启动选项 (Options对象通常位于各浏览器的 WebDriver 模块下,列如:from selenium.webdriver.浏览器名称.options import Options),建议优先使用options 参数来设置浏览器(options 基于 capabilities,在实例化某个浏览器的Options对象时会自动写入该浏览器预设的 capabilities)

  • service_log_path:驱动程序存放日志文件的位置

  • keep_alive:表示在与 ChromeDriver 进行链接时,是否带上 HTTP 请求头Connection: keep-alive,既是否使用长链接,布尔类型参数,默认值为True

  • service_args:浏览器驱动程序的参数,根据所使用的浏览器驱动不同,参数也有可能不同。

Edge浏览器部分

  • executable_path:浏览器驱动程序路径,如果没有制定,则默认使用环境变量PATH中设置的路径
  • capabilities:非浏览器特定的字典对象,传入浏览器启动参数时需要使用到
    port:驱动程序启用的端口号,如果不填写,则自动使用任意闲置的端口号,默认参数为0
    verbose:是否在服务中设置详细日志记录
    service_log_path:驱动程序存放日志文件的位置
    log_path:不推荐使用的 service_log_path 参数
    keep_alive:表示在与 EdgeDriver 进行链接时,是否带上 HTTP 请求头Connection: keep-alive,既是否使用长链接,布尔类型参数,默认值为True


元素定位

web自动化的难点和重点之一,就是如何 选择 我们想要操作的web页面元素。

id定位

id 定位 driver.findElement(By.id(“id的值”));

如果元素有id属性 ,这个id 必须是当前html中唯一的。所以如果元素有id, 根据id选择元素是最简单高效的方式。

  1. 使用WebDriver对象的findElement函数定义一个Web页面元素
  2. 使用findElements函数可以定位页面的多个元素

使用 find_elements 选择的是符合条件的 所有 元素, 如果没有符合条件的元素, 返回空列表

List<WebElement> listOfElements = driver.findElements(By.xpath("//div"));
webElement.findElements(By.tagName("tr"));
  • 如果没有匹配条件的元素,Find Elements命令将返回一个空列表

使用 find_element 选择的是符合条件的 第一个 元素, 如果没有符合条件的元素, 抛出 NoSuchElementException 异常

定位的页面元素需要使用WebElement对象来存储,以便后续使用


class定位

class 定位    driver.findElement(By.className(“class属性”));

 //企查查webDriver.get("https://www.qcc.com/");TimeUnit.SECONDS.sleep(2);//查企业 查老板 查风险 查招标 找关系List<WebElement> elements = webDriver.findElements(By.className("search-type"));

class 属性通常用于指向样式表的类

在html中,class规定元素的类名,语法格式为“<元素名称 class="value">”。class属性大多数时候用于指向样式表中的类(class)。

html标签是允许定义多个class类名的。比如:

<div class = "exp1 exp2"></div>

上边这个div就用到了exp1、exp2这两个class类,对于个数是没有限制,只需每个类名之间用空格隔开就好。


tag 名 定位

TagName 标签名称定位    driver.findElement(By.tagName(“标签名称”));

选择所有的tag名为 div的元素,如下所示


name定位

name定位    driver.findElement(By.name(“name的值”));

css定位

CSS定位为的优势在于定位速度比Xpath定位快,且比Xpath定位更加稳定

css 方式定位    driver.findElement(By.cssSelector(“css表达式”));

Xpath定位

xpath定位方式

xpath 是XML Path的简称, 用于在XML文档中选择文档中的节点。基于XML树状文档结构,Xpath语言可以在整棵树中寻找指定的节点。

xpath 方式定位
driver.findElement(By.xpath(“xpath表达式”));

xpath 有两种表示方法,绝对路径和相对路径,

绝对路径是指从根开始,以/开始,如/html/body/div,

相对路径是指在一个路径下,另外的路径以这个路径作为参照,以//开始。从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。

  • XPath表达式中的//表示在HTML文档的全部层级位置进行查找

举例如下:

//百度一下
webDriver.get("https://www.baidu.com");
WebElement element = webDriver.findElement(By.xpath("//*[@id='su']"));

这里为啥是//*[@] 呢?

  • //表示从任意位置去查找
  • *是标签名
  • @是属性定位

强烈建议使用相对路径和属性值结合的定位方式来编写xpath定位表达式。如

By.xpath("//*[@id='su']")

xpath获取

xpath获取技巧:网页的html是一种特殊的XML文档。使用浏览器调试工具,可以直接获取xpath语句

右键-检查(或者F12),然后点击这个箭头,就可以在浏览器上选择元素了

使用Chrome 来直接获取元素的XPath.

通过层级关系和索引定位(索引从1开始):

//*[@id="content"]/div/div[2]/div[4]/div[2]/h2/div[2]/form/div

标签+属性定位

XPath通过idnameclass属性定位。语法如下:

//标签名[@属性名='属性值']
//用XPath通过id属性定位  
element1 = driver.find_element_by_xpath("//input[@id='kw']")//用XPath通过name属性定位  
element2 = driver.find_element_by_xpath("//input[@name='wd']")//用XPath通过class属性定位  
element3 = driver.find_element_by_xpath("//*[@class='s_ipt']")

总结

  1. 如果不想制定标签名称,可以用*号表示任意标签。
  2. 有时候同一个属性,同名的比较多,这时候可以通过标签筛选下,定位更准一点。
  3. 如果想制定具体某个标签,就可以直接写标签名称

List pageUl = ar.driver.findElements(By.xpath("//ul[@class='bfe-pager']"));//获取页数


层级定位

通过层级关系定位,注意:最终定位的是子标签....语法如下:

 //父标签名[@父标签属性名='属性值']/子标签

在页面中,定位下面代码片段中的<input>标签

<p id="p1"><label for="userA">账号A</label><input required="" value="">
</p>

答案如下:

driver.find_element_by_xpath("//p[@id='p1']/input")

索引定位

索引定位元素,语法如下:

//父标签名[@父标签属性名='属性值']/子标签[索引值]   索引从1开始

比如我要定位如下图片的“京东家电连接”

答案是:

//*[@id=\"navitems-group1\"]/li[2]/a

用id="navitems-group1"定位到如下图片这里,这些是一些li标签

//*[@id="navitems-group1"]/li[1]/a//*[@id="navitems-group1"]/li/a

注意:如果是第一个元素,索引值可以不加。因为不加索引值会选取ul下的全部li标签
而我们用的是单数定位形式,默认选择第一个。


文本定位

//标签名[text()=‘文本’]

xpath定位时,定位某一元素不好定时,可以定位其子级元素,然后通过 /… 定位到它的父级元素

HTML实例:<button type="button" class="ant-btn ant-btn-primary"><span>新 建</span></button>
xpath定位://span[text()='搜 索']/..

逻辑定位

XPath逻辑定位说明:

  1. xpath还有一个比较强的功能,可以支持与(and)、或(or)、非(not)。
  2. 一般用的比较多的是and运算,同时满足两个属性。

比如一个日期输入框无法输入

1

//获取当前页所有的数据
List datasaaa = ar.driver.findElements(By.xpath("/html/body/div[11]/table/tbody/tr/td[not(contains(@class, \"outMonthDay\"))]"));	 
System.out.println("datasaaa.size():"+datasaaa.size());
for(int i=0;i<datasaaa.size();i++){String text=datasaaa.get(i).getText().trim();System.out.println("text:" + text);if(Integer.parseInt(text)==day1){datasaaa.get(i).click();break;}
}

判断元素是否存在

场景:比如银行某些账号的对账提醒,但是不是所有的账号都有。所以要先判断元素是否存在

捕获异常方式  

捕获异常是使用findElement()方法无法获取元素则会抛出异常,如果找到元素则会返回True

//通过异常判断
public static boolean isElementExist(WebDriver driver, String xpath) {try {WebElement element = driver.findElement(By.xpath(xpath));return true;} catch (Exception e) {e.printStackTrace();return false;}
}

弊端:只要页面上有元素,不几个,都返回True

比如:在打开百度贴吧的时候,会有登录提醒。做一个判断,如果存在则关闭该弹窗

driver.get("https://tieba.baidu.com/");
//只需要设置一次,所有的元素都可有最多 10s 的等待加载的时间(默认0)
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
//判断xpath是否存在,存在则点击关闭弹窗
boolean exist = isElementExist(driver, "//*[@id=\"tiebaCustomPassLogin\"]/div[2]/span");


父子、兄弟、相邻节点定位方式

相邻节点定位

比如,我要获取表格的总记录数。此时因为一个变化的值,

如果查询条数少,只有一页。则获取页数可以用xpath :/ul/li[5]/b

如果查询条数过多,则xpath发生变化:/ul/li[6]/b

此时,是否可以用兄弟节点定位。通过“>”来定位。“>”是可以用属性定位的//a[@class=\"next\"]


获取文本

//h5[text()='可用余额'

//span[text() = '全部']/parent::label/span[1]

子节点定位父节点

result = html.xpath('//a[@id="parentSpan"]/text()')

获取 href 属性

# 8、获取 href 属性
result = html.xpath('//a[@id="parentSpan"]/@href')

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

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

相关文章

1、Java简介+DOS命令+java的编译运行(字节码/机器码、JRE/JVM/JDK/JIT的区别)+一个简单的Java程序

前言&#xff1a;本文属于黑马程序员和javaguide的混合笔记&#xff0c;仅作学习分享使用&#xff0c;建议感兴趣的小伙伴去看黑马原视频或javaguide原文。如有侵权&#xff0c;请联系删除。 Java类型&#xff1a; JavaSE 标准版&#xff1a;以前称为J2SE&#xff0c;主要用来…

网站开发:HTML+CSS - 表格与表单

1. 前言​​​​​​​​​​​​​​ 表格与表单在网页开发中非常重要。表格使得用户可以更简洁清晰的去浏览信息。 表单提供了一种在客户端&#xff08;浏览器&#xff09;和服务器之间进行数据交互的方式。 以下为其主要作用&#xff1a; 用户交互和数据输入&#xff1a;表…

Android Audio分区——音频分区加载流程(三)

前面文章介绍了车载多区音频基础&#xff0c;并且介绍了音频分区相关类及对应功能&#xff0c;这里我们就来看一下音频分区的解析过程。 一、音频分区加载 音频分区的加载是在 CarAudioService 的初始化函数 init() 流程中进行的。 1、CarAudioService.java 源码位置&#x…

【ragflow】安装2:源码安装依赖

中文文档【ragflow】安装1: docker:失败官方说的成功 docker 安装的启动失败 重新来一遍,不会重新拉取: root@k8s-master-pfsrv:/home/zhangbin/perfwork/rag# cd ragflow/ root@k8s-master-pfsrv:/home/

USB3202N多功能数据采集卡16位模拟量250K频率LabVIEW采集卡

品牌&#xff1a;阿尔泰科技 系列&#xff1a;多功能数据采集卡 概述&#xff1a; USB3202N多功能数据采集卡&#xff0c;LabVIEW无缝连接&#xff0c;提供图形化API函数&#xff0c;提供8通道&#xff08;RSE、NRSE&#xff09;、4通道&#xff08;DIFF&#xff09;模拟量输…

向量和矩阵学习笔记

向量和矩阵学习笔记 Ps:因为本人实力有限&#xff0c;有一部分可能不太详细&#xff0c;若有补充评论区回复&#xff0c;QWQ 向量 向量的定义 首先&#xff0c;因为我刚刚学到高中的向量&#xff0c;对向量的看法呢就是一条有长度和方向的线&#xff0c;不过这在数学上的定…

C/C++入门案例01

文章目录 写在前面1. 你好&#xff0c;世界&#xff01; (Hello, World!)2. 基本的算术运算3. 判断奇偶数4. 计算数组元素的和5. 求最大值和最小值6. 简单的计算器7. 字符串反转8. 计算阶乘9. 查找质数10. 冒泡排序 系列推荐 写在前面 以下是10个适合初学者的C语言入门案例&am…

【如何在MacOS升级ruby版本】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

C++期末知识点概述

《大学 C知识点概述》 在大学的计算机课程中&#xff0c;C作为一门重要的编程语言&#xff0c;有着广泛的应用和丰富的知识点。 一、基础语法 数据类型&#xff1a;C包含多种数据类型&#xff0c;如整数类型&#xff08;int、short、long 等&#xff09;、浮点类型&#xff…

Unity(2022.3.41LTS) - 音频

目录 一、音频系统概述 二、音频资源类型 三、音频组件 四、音频空间定位 五、音频效果处理 六.音乐框架设计 一、音频系统概述 Unity 的音频系统允许开发者在游戏中添加各种声音效果&#xff0c;包括背景音乐、音效、环境音等。它提供了丰富的功能来控制音频的播放、音…

MIT 6.5940 EfficientML.ai Fall 2023: Lab 1 Pruning

EfficientML.ai Lec 3 - Pruning and Sparsity (Part I) MIT 6.5940, Fall 2023, Zoom 本文是EfficientML.ai Fall 2023课程作业1练习答案&#xff0c;在本次练习里将会对经典的分类神经网络进行剪枝处理&#xff0c;减少模型大小和延迟。The goals of this assignment are as …

python破解[5分钟解决拼多多商家后台字体加密]

可【QQ群】拿源码 进入经营总览想把数据存下来发现返回的json数据部分空白如下 这可怎么办 稳住应该是字体的问题&#xff0c;可能是多多自己实现了某种字体&#xff0c;我们去找他的js 发现如我们所想&#xff0c;进行跟踪&#xff0c;发现的确是在css端进行了字体替换&am…

Servlet, Filter, Listener 启动与执行顺序

Servlet, Filter, Listener 启动与执行顺序 1、启动顺序 **Listener -> Filter -> Servlet**2、记忆口诀3、执行顺序 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java Web应用中&#xff0c;Servlet、Filter和Listener的启动与执…

从0开始深度学习(2)——自动微分

1 微积分 1.1 导数和微分 略 1.2 偏导数 略 1.3 梯度&#xff08;gradient&#xff09; 1.3.1 定义 对于一个多变量函数 f ( x 1 , x 2 , … , x n ) f\left(x_{1}, x_{2}, \ldots, x_{n}\right) f(x1​,x2​,…,xn​)其中点 a ( a 1 , a 2 , … , a n ) \mathbf{a}(a_…

【卷起来】VUE3.0教程-01-环境搭建与安装

​分享不易&#xff0c;耗时耗力&#xff0c;麻烦给个不要钱的关注和赞吧 &#x1f332; 什么是VUE Vue 是一个框架&#xff0c;也是一个生态。其功能覆盖了大部分前端开发常见的需求。但 Web 世界是十分多样化的&#xff0c;不同的开发者在 Web 上构建的东西可能在形式和规模…

SpringSecurity笔记整理

自定义登录页面 编写登录页面<!DOCTYPE html> <html xmlns"http://www.w3.org/1999/xhtml" xmlns:th"https://www.thymeleaf.org"> <head><title>Please Log In</title> </head> <body> <h1>Please Log …

鸿蒙OpenHarmony、HarmonyOS、HarmonyOS NEXT的区别

鸿蒙OpenHarmony、HarmonyOS、HarmonyOS NEXT的区别 OpenHarmony&#xff1a;开源底层。HarmonyOS&#xff1a;闭源手机系统&#xff0c;兼容安卓生态。HarmonyOS NEXT&#xff1a;纯血鸿蒙&#xff0c;不兼容安卓。 OpenHarmony&#xff08;开源&#xff09; 开源地址&…

Question mutiple pdf‘s using openai, pinecone, langchain

题意&#xff1a;使用 OpenAI、Pinecone 和 LangChain 对多个 PDF 文件进行提问。 问题背景&#xff1a; I am trying to ask questions against a multiple pdf using pinecone and openAI but I dont know how to. 我正在尝试使用 Pinecone 和 OpenAI 对多个 PDF 文件进行提…

【Linux】保姆级 Linux 常见命令使用

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录 1. Linux 是什么1.1 Linux 是什么1.2 关于 Linux 我们需要学什么 2. 需提前准备的东西2.1 环境 —— 如何获取…

使用 Eigen 库中的 Kronecker 积运算

前言 在数值计算和线性代数的众多应用中&#xff0c;Kronecker 积&#xff08;Kronecker Product&#xff09;是一种常用的矩阵运算。Eigen 是一个高性能的 C 数值计算库&#xff0c;广泛用于科学计算和工程应用中。在 Eigen 库中&#xff0c;Kronecker 积运算属于不常用的扩展…