selenium学习笔记

什么是selenium

比较官方的解释

Selenium是一个自动化测试工具,用于在Web应用程序中模拟用户操作。它提供了一组API,可以通过编程方式控制浏览器,并模拟用户的交互行为,例如点击、输入文本和导航等。Selenium支持多种编程语言,包括Java、C#、Python、Ruby、JavaScript等,并可以在多个浏览器和操作系统上运行测试。Selenium的目标是帮助测试人员自动化测试过程,提高测试效率和测试质量。

个人的简单理解

  1. 浏览器驱动可以操作浏览器,不用selenium也能实现代码控制浏览器的效果,就是需要自己查询浏览器启动提供的功能,
  2. selenium可以看成是浏览器驱动的工具类,在项目中引入seleniu,就能通过selenium方便的操作浏览器

image-20240528093739763

用途

  1. 自动化测试
  2. 爬虫,这里主要做爬虫使用

各种爬虫的比较

  1. 直接通过http工具调用接口

    例如HttpClient、OkHttp、RestTemplate等,此种方法需要注意数据的完整性,页面上一个操作可能会涉及到多个接口的调用,如果调用不全可能会造成一些异常数据,另外如果请求中有一些自定义的加密请求头,就需要扒前端源码,找到加密算法,前端源码往往是经过编译后的,可读性比较差,想到加密算法比较费劲

Java环境搭建

下载对应的浏览器和驱动

浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可),浏览器和对应的驱动见附件

引入依赖

<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version>
</dependency>

此种方法不是最佳实践,最佳实践是连接已经打开的浏览器,退出时仅仅退出浏览器驱动,不退出已经打开的浏览器,见最佳实践部分

public class HelloSelenium {@SneakyThrowspublic static void main(String[] args) {// 设置 ChromeDriver 的路径System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe");// 配置 ChromeOptionsChromeOptions options = new ChromeOptions();// 指定特定版本的 Chrome 浏览器路径 浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可)options.setBinary("C:\\118.0.5993.70\\chrome-win64\\chrome.exe");// 可选:无头模式,不打开浏览器窗口 如果做爬虫不打开浏览器某些网站过不去,可能会遇到Enable JavaScript and cookies to continue// options.addArguments("--headless");// 解决一些系统的图形化渲染问题options.addArguments("--disable-gpu");// 在某些系统上需要添加此参数options.addArguments("--no-sandbox");// 解决资源共享内存的问题options.addArguments("--disable-dev-shm-usage");// 创建 ChromeDriver 实例WebDriver driver = new ChromeDriver(options);// 为浏览器驱动driver创建一个等待器,循环等待,直到条件达成或者超时,如果条件未达成超时就会跑出异常WebDriverWait wait = new WebDriverWait(driver, 10);try {// 访问指定的 URLdriver.get("http://localhost:8080");// 直接使用driver.findElement可能元素还没有加载出来读取不到,wait.until会一直检测,直到找到元素或者超时// WebElement nameInput = driver.findElement(By.xpath("/html/body/div[1]/form/div[1]/div/div/input"));WebElement nameInput = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[1]/form/div[1]/div/div/input")));nameInput.sendKeys("张无忌");List<WebElement> buttons = driver.findElements(By.tagName("button"));WebElement queryButton = buttons.stream().filter(item -> "查询".equals(item.getText())).findFirst().get();queryButton.click();} catch (Exception e) {e.printStackTrace();} finally {// 方便观察浏览器,避免马上退出Thread.sleep(10 * 1000);// 退出浏览器驱动程序,关闭所有关联的窗口。(如果不退出浏览器驱动器不会结束,多次运行会启动多个浏览器驱动,占用系统资源)driver.quit();}}

options全部参数可参考https://peter.sh/experiments/chromium-command-line-switches/

常用方法

// 请求一个页面,不支持前进和后退切换
driver.get(url); 
// 和get类似,支持前进和后退切换
driver.navigate().to(url); 
// 退到上一个页面 ,前提必须前进了一个页面才能回退
driver.navigate().back(); 
// 指前进到下一个页面 ,前提是必须后退后才能前进
driver.navigate().forward(); 
// 刷新当前页面
driver.navigate().refresh(); 
// 通用搜索,第一个 , By里包含常用的各种搜索
WebElement findElement(By by); 
// 通用搜索,多个,By里包含常用的各种搜索
List<WebElement> findElements(By by); 
// 关闭当前窗口,如果它是当前打开的最后一个窗口,则退出浏览器。
driver.close();
// 退出此驱动程序,关闭每个相关窗口。
driver.quit(); 

WebElement常用方法

元素定位

根据id属性匹配

public static By id(String id) {return new ById(id);
}

根据a标签内容匹配

public static By linkText(String linkText) {return new ByLinkText(linkText);
}

根据a标签内容模糊匹配

public static By partialLinkText(String partialLinkText) {return new ByPartialLinkText(partialLinkText);
}

根据name属性匹配

public static By name(String name) {return new ByName(name);
}

根据标签名字匹配

public static By tagName(String tagName) {return new ByTagName(tagName);
}

根据路径匹配

路径可直接在浏览器中拷贝

public static By xpath(String xpathExpression) {return new ByXPath(xpathExpression);
}

根据类名匹配

public static By className(String className) {return new ByClassName(className);
}

根据css选择器匹配

public static By cssSelector(String cssSelector) {return new ByCssSelector(cssSelector);
}

元素操作

  1. click():点击该元素。
  2. submit():将表单提交到该元素所在的表单。
  3. sendKeys(CharSequence… keysToSend):将指定的字符序列发送到该元素。例如向输入框输入文本。
  4. clear():清除该元素的内容。
  5. getTagName():获取该元素的标签名称。
  6. getAttribute(String name):获取该元素指定属性的值。
  7. getText():获取该元素的文本内容。
  8. isEnabled():判断该元素是否可用。
  9. isSelected():判断该元素是否被选中。
  10. isDisplayed():判断该元素是否可见。
  11. getLocation():获取该元素在页面中的位置。以Point对象表示,包含xy坐标。
  12. getSize():获取该元素的大小,以Dimension对象表示,包含widthheight
  13. getCssValue(String propertyName):获取该元素指定CSS属性的值。

等待机制

显式等待

  • 使用 WebDriverWaitExpectedConditions 来等待特定条件(如元素可点击、元素存在等)。
// 配置 ChromeOptions
ChromeOptions options = new ChromeOptions();
// 指定特定版本的 Chrome 浏览器路径 浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可)
options.setBinary("C:\\118.0.5993.70\\chrome-win64\\chrome.exe");
WebDriver driver = new ChromeDriver(options);
// 创建一个显示等待器,超时时间10S
WebDriverWait wait = new WebDriverWait(driver, 10)
// 循环寻找一个h3元素,10s内找到返回该元素,10s找不到抛出异常
WebElement h3 = wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("h3")));  

隐式等待

隐式等待在Java中通过WebDrivermanage().timeouts().implicitlyWait方法实现。以下是一个示例代码:

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;public class ImplicitWaitExample {public static void main(String[] args) {// 设置ChromeDriver的路径System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");// 初始化WebDriverWebDriver driver = new ChromeDriver();// 设置隐式等待时间为10秒driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);// 打开一个网页driver.get("http://example.com");try {// 查找元素 如果10s内找到则返回元素,如果10秒没有找到则抛出异常WebElement element = driver.findElement(By.id("myElement"));// 操作元素element.click();} catch (Exception e) {e.printStackTrace();} finally {// 关闭浏览器driver.quit();}}
}

在这个示例中,implicitlyWait方法设置了一个最长等待时间为10秒,在查找元素时,如果元素未立即出现,WebDriver会等待这个时间内不断尝试查找元素。

显示等待与隐式等待的区别

  1. 显示等待是指在代码中明确指定等待条件和等待时间,直到条件成立或等待时间到期,程序才会继续执行下一步操作。显示等待可以根据不同的条件进行等待,例如元素的可见性、可点击性、文本内容、属性值等。显示等待可以通过ExpectedConditions类来实现。

2 隐式等待是指在代码中设置一个全局等待时间,在此时间内如果元素没有立即出现,程序将等待指定的时间,等待元素出现。隐式等待适用于整个测试用例,而不是针对某个特定的元素。隐式等待可以通过WebDriver.Timeouts.implicitlyWait()方法来设置。。

最佳实践

打开与关闭浏览器驱动

开启浏览器debug端口

连接到已经打开的浏览器,需要浏览器开启debug端口,简单的开启方法

  1. 为chrome.exe创建一个快捷方式

  2. chrome.exe创建>>右键>>属性>>目标后面添加--remote-debugging-port=9222(注意chrome.exe与新加内容之间有个空格,端口可以自由定义)

    image-20240527195720351

  3. 直接打开浏览器即可

  4. 检查浏览器是否开启了debug端口,访问http://localhost:9222/json,返回一下内容说明浏览器成功开启了debug端口,9222是自定义端口

[ {"description": "","devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844","id": "B3C592C54EB3552A0F5D76706A6EF844","title": "emp","type": "page","url": "http://localhost:8080/","webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844"
} ]

创建浏览器驱动并连接到已经打开的浏览器

public void openChrome() {// 设置 ChromeDriver 的路径System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe");// 配置 ChromeOptionsChromeOptions options = new ChromeOptions();options.setExperimentalOption("debuggerAddress", "localhost:9222");// 创建 ChromeDriver 实例driver = new ChromeDriver(options);}

退出浏览器驱动ChromeDriver

public void closeChrome() {// 退出浏览器驱动程序driver.quit();
}

不要让ChromeDriver打开浏览器,让ChromeDriver链接到已经打开的浏览器,好处如下

  1. 退出浏览器驱动时不退出浏览器,如果用浏览器驱动打开浏览器,调用driver.quit()方法退出浏览器驱动时会关闭浏览器(有时候我们想看到最好操作的结果,不希望退出浏览器)
  2. ChromeDriver打开的浏览器中不一定有身份信息,可能需要登录.自己可以提前打开好浏览器,并且登录相关网站

元素定位

  1. 如果页面元素相对比较固定,可以直接用xpath定位,简单直接,xpath可以直接从浏览器赋值

image-20240527192312255

复制出来的xpath直接粘贴到代码里即可

/html/body/div[2]/div[1]/div/div[1]/div/div/div[1]/div/form/div[2]/div/div[1]/div[1]/textarea

如果前端页面频繁更新,页面元素位置经常变动,就不太适合这种方式了

  1. 如果页面元素经常变动,但是提示语或者某些属性比较固定,可以拿到所有这个类型的元素,再根据固定的属性过滤
List<WebElement> textareaList = driver.findElements(By.tagName("textarea"));
for (WebElement textarea : textareaList) {String placeholder = textarea.getAttribute("placeholder");if (placeholder.contains("内容概要+适用人群+使用场景及目标+其他说明")) {// 拿到了资源描述文本框}
}

selenium实战

基于selenium的crud

  1. 启动项目
  2. crud详见代码com.study.selenium.EmpCRUDTest
  3. 效果见演示视频

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

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

相关文章

9.4 Go语言入门(运算符)

Go语言入门&#xff08;运算符&#xff09; 目录三、运算符1. 算术运算符2. 关系运算符3. 逻辑运算符4. 位运算符5. 赋值运算符6. 其他运算符7. 运算符优先级 目录 Go 语言&#xff08;Golang&#xff09;是一种静态类型、编译型语言&#xff0c;由 Google 开发&#xff0c;专注…

若依启动run-modules-system.bat报错问题解决方案

在启动run-modules-system.bat时遇到了一些问题,在网上搜索无果后,排查解决完毕 1.启动nacos时,报错如下 Error creating bean with name grpcClusterServer: Invocation of init method failed; nested exception is java.io.IOException: Failed to bind to address 0.0.0.0…

SQL实战 将学生信息进行 行转列输出

表countries 数据如下&#xff1a; namecontinentJaneAmericaPascalEuropeXiAsiaJackAmerica数据建表来源&#xff1a; SQL试题使得每个学生 按照姓名的字⺟顺序依次排列 在对应的⼤洲下⾯展示为如下的数据样式&#xff1a; namecontinentJane, JackAmericaXiAsiaPascalPasca…

Python开发 —— 对象type、object、class

1. "Python中一切皆为对象"的理解 在Python中&#xff0c;一切皆为对象的意思是指&#xff1a;无论是数字、字符串、函数、类、模块等任何数据类型&#xff0c;都可以被看做是一个对象。每个对象都具有自己的属性和方法&#xff0c;可以被操作和调用。 例如&#xff…

linux--实时性优化

linux--实时性优化 1 介绍2 实时性需求3 代表性实时系统4 嵌入式系统嵌入式软件系统结构处理器时钟节拍多任务机制任务调度方式任务调度算法时间片调度算法优先级调度算法基于优先级的时间片调度算法 5 cyclictest 测试工具命令说明命令分析参数含义 6 linux 实时性改进某版本上…

04-Vue:ref获取页面节点--很简单

目录 前言在Vue中&#xff0c;通过 ref 属性获取DOM元素使用 ref 属性获取整个子组件&#xff08;父组件调用子组件的方法&#xff09; 前言 我们接着上一篇文章 03-02-Vue组件之间的传值 来讲。 下一篇文章 05-Vue路由 在Vue中&#xff0c;通过 ref 属性获取DOM元素 我们当然…

装机必备——Bandizip7.33安装教程

装机必备——Bandizip7.33安装教程 软件下载 软件名称&#xff1a;Bandizip7.33 软件语言&#xff1a;简体中文 软件大小&#xff1a;8.42M 系统要求&#xff1a;Windows7或更高&#xff0c; 64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM4G或更高 下载通道①迅…

JS逆向之企名科技

文章目录 初步分析定位js编写完整代码参考文献初步分析 目标网址:企名科技 抓包分析,发现是post请求 请求代码如下: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import requestsheaders = {Connection:

Android应用开发之AndroidManifest.xml

一.AndroidManifest.xml介绍 1.定义 AndroidManifest官方解释是应用清单&#xff08;manifest意思是货单&#xff09;&#xff0c;每个应用的根目录中都必须包含一个&#xff0c;并且文件名必须一模一样。 它是Android程序的全局配置文件&#xff0c;是每个 android程序中必须…

韭菜收割项目

最近在玩股票&#xff0c;被人当成韭菜收割了一顿。高点追涨&#xff0c;第二天直接跌停。以为是低点&#xff0c;想抄底&#xff0c;结果别人直接抄家&#xff0c;血亏!!! 作为一个程序员&#xff0c;还是好好敲代码赚钱好了&#xff0c;一步一步。想不劳而获是不可能的。 我写…

[智能AI摄像头]使用docker搭建RV1126开发环境

创建ubuntu docker 创建dockerfile # 设置基础镜像为Ubuntu 18.04FROM ubuntu:20.04# 设置作者信息MAINTAINER warren "2016426377qq.com"# 设置环境变量&#xff0c;用于非交互式安装ENV DEBIAN_FRONTENDnoninteractive# 备份源列表文件RUN cp -a /etc/apt/source…

视频号小店脱颖而出,一跃成为电商黑马!马化腾要实现电商梦了?

大家好&#xff0c;我是喷火龙。 视频号这个名字在电商的圈子里是经常被提起的&#xff0c;特别是从今年开始&#xff0c;很多之前的电商项目不行&#xff0c;加上传统电商平台开始走下坡路&#xff0c;于是很多电商人都把视频号小店作为一个新的突破口。 因为视频号小店足够…

MySQL 数据备份实战

文章目录 前言简介一、数据备份导出SQL文件第一步&#xff1a;登录MySQL第二步&#xff1a;选中数据库第三步&#xff1a;数据导出SQL文件 二、还原SQL文件第一步&#xff1a;登录MySQL第二步&#xff1a;创建数据库第三步&#xff1a;选中数据库第三步&#xff1a;终端命令行语…

代码随想录算法训练营第四十二天 | 62.不同路径、63. 不同路径 II

62.不同路径 代码随想录 视频讲解&#xff1a;动态规划中如何初始化很重要&#xff01;| LeetCode&#xff1a;62.不同路径_哔哩哔哩_bilibili 解题思路 1.dp[i][j]表示从00走到ij有多少种方式 2. ij可以由i-1&#xff0c;j往右走一步&#xff0c;或者i&#xff0c;j-1往想下走…

1791.找出星形图的中心节点

刷算法题&#xff1a; 第一遍&#xff1a;1.看5分钟&#xff0c;没思路看题解 2.通过题解改进自己的解法&#xff0c;并且要写每行的注释以及自己的思路。 3.思考自己做到了题解的哪一步&#xff0c;下次怎么才能做对(总结方法) 4.整理到自己的自媒体平台。 5.再刷重复的类…

电脑中msvcp100.dll丢失了怎么办?总结7种靠谱的解决方法

msvcp100.dll 文件是 Microsoft Visual C 2010 Redistributable 的一部分&#xff0c;这是一个重要的动态链接库&#xff08;DLL&#xff09;文件&#xff0c;用于存储许多程序共同使用的代码和资源。它是执行 C 编写的应用程序所必需的&#xff0c;尤其是那些使用 Visual C 20…

全局配置Maven

如果开着项目&#xff0c;就file->close project 如果创建有问题可以转到这篇rIDEA2024创建maven项目-CSDN博客https://blog.csdn.net/weixin_45588505/article/details/139271562?spm1001.2014.3001.5502

Layui 项目打开左侧菜单空白解决方案

home/index.html 页面中 替换 navigation 为 menu

海外仓ERP系统:赋能海外仓,实现标准化管理

随着业务规模的不断发展和业务类型的复杂度逐渐提升&#xff0c;传统的海外仓管理模式已经很难适应现在的情况了。对海外仓企业来说&#xff0c;一套合适的海外仓管理erp系统可以起到很大的辅助作用。 不过很多小型海外仓企业会纠结于是同时选择企业erp系统和海外仓管理系统&a…

图论(五)-最短路

一、Bellman-Ford算法 算法思想&#xff1a;通过 n 次循环&#xff0c;每次循环都遍历每条边&#xff08;共 m 条边&#xff09;&#xff0c;进而更新节点的距离&#xff0c;每次循环至少可以确定一个点的最短路&#xff0c;循环 n 次&#xff0c;求出 n 个点的最短路 时间复杂…