Java使用Selenium实现自动化测试以及全功能爬虫

2023-11-05

1 你听没听说过Selenium?

1.1 自动化测试

提到Selenium,便离不开自动化测试。

自动化测试,就是把手工进行的测试过程,转变成机器自动执行的测试过程。

自动化测试有如下优点

  • 对程序的回归测试更方便。 这可能是自动化测试最主要的任务,特别是在程序修改比较频繁时,效果是非常明显的。 …
  • 可以运行更多更繁琐的测试。 …
  • 可以执行一些手工测试困难或不可能进行的测试。 …
  • 更好地利用资源。 …
  • 测试具有一致性和可重复性。 …
  • 测试的复用性。 …
  • 增加软件信任度。

1.2 Selenium

因为对自动化测试卓越体验的追求,众多自动化测试工具应运而生,Selenium就是其中最出色的一款。

Selenium 是一个用于Web应用程序测试的工具。他是一款浏览器仿真程序 可以像真正的用户在操作一样操作浏览器。

Selenium支持全部主流的浏览器,支持主流的编程语言,包括:Java、Python、C#、PHP、Ruby、JavaScript等,基于标准的 WebDriver 语法规范,
同时支持所有基于web 的管理任务自动化。

Selenium由多个软件工具组成。每个工具都有一个特定的角色。主要包含以下工具:

  • Selenium IDE Selenium IDE(集成开发环境)是一个构建测试脚本的原型工具
  • Selenium RC 是Selenium的远程控制(又称Selenium1.0)
  • Selenium Grid 可以测试集分布在多个环境中并行运行测试用例。

2 java中集成Selenium

Selenium支持主流的编程语言,包括:Java、Python、C#、PHP、Ruby、JavaScript;

Q:为什么选择java 而不是 python?

A:Python是简洁高效的脚本语言,有时间我再出一篇Python版本的。

2.1 maven添加依赖

在java中使用Selenium很简单,你只需要添加如下依赖:

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
</dependency>
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>23.0</version>
</dependency>
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.2</version>
</dependency>

2.2 添加浏览器驱动

当selenium升级到3.0之后,对不同的浏览器驱动进行了规范。如果想使用selenium驱动不同的浏览器,必须单独下载并设置不同的浏览器驱动。

在java中使用不同浏览器:
首先配置驱动属性,指定驱动文件路径

System.setProperty("webdriver.chrome.driver", "Q:\\chromedriver.exe");

获取WebDriver并打开一个新的浏览器窗口

WebDriver driver = new ChromeDriver();    //Chrome浏览器
WebDriver driver = new FirefoxDriver();   //Firefox浏览器
WebDriver driver = new EdgeDriver();      //Edge浏览器
WebDriver driver = new InternetExplorerDriver();  // Internet Explorer浏览器
WebDriver driver = new OperaDriver();     //Opera浏览器
WebDriver driver = new PhantomJSDriver();   //PhantomJS

注:可以在linux中使用无窗口模式,后续会讲到

简单样例

public class Itest {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "Q:\\chromedriver.exe");
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.ytooo.org");
  
        Thread.sleep(10000);
        driver.close();
    }
}

2.2 selenium元素定位

2.2.1 定位元素
  • findElement(By.id()) driver.findElement(By.id(“kw”))

  • findElement(By.name()) driver.findElement(By.name(“wd”))

  • findElement(By.className()) driver.findElement(By.className(“s_ipt”))

  • findElement(By.tagName()) driver.findElement(By.tagName(“input”))

  • findElement(By.linkText())

<a class="mnav" href="http://news.baidu.com" name="tj_trnews">新闻</a>
<a class="mnav" href="http://www.hao123.com" name="tj_trhao123">hao123</a>
driver.findElement(By.linkText("新闻")

driver.findElement(By.linkText("hao123")
  • findElement(By.partialLinkText())

driver.findElement(By.partialLinkText(“新”)

  • findElement(By.xpath()) driver.findElement(By.xpath("//*[@id=‘kw’]"))
  • findElement(By.cssSelector()) driver.findElement(By.cssSelector(“html > body > form > span > input”)
2.2.2 获取元素列表
    driver.findElements(By.cssSelector(".for.list td"));

获取到的元素列表为 List 对象,不建议直接循环来获取 元素对象,而是从根中重新获取,以避免获取元素失败

List<WebElement> heads = driver.findElements(By.cssSelector(".for.list td"));

for (int i = 0; i < heads.size(); i++) {
    String href = driver.findElements(By.cssSelector(".for.list td")).get(i).getText();
}
2.2.3 下拉框选择
WebElement el = driver.findElement(By.xpath("//select"));
Select sel = new Select(el);
sel.selectByValue("20");

2.3 设置元素等待

WebDriver提供了两种类型的等待:显式等待和隐式等待。

2.3.1 显式等待

显式等待, 针对某个元素等待

WebDriverWait wait = new WebDriverWait(driver,10,1);
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".for.list")));
2.3.1 显式等待

隐式等待, 针对某个元素等待

driver.manage().timeouts().pageLoadTimeout(5, TimeUnit.SECONDS);

2.4 WebElement常用方法* clear() 清除文本。

  • sendKeys(*value) 模拟按键输入。
  • click() 单击元素
driver.findElement(By.id("username")).sendKeys("用户名");
driver.findElement(By.id("password"))sendKeys("密码");
driver.findElement(By.id("commit")).click;

2.5 键鼠操作

2.5.1 Actions 键鼠操作
  • contextClick() 右击
  • clickAndHold() 鼠标点击并控制
  • doubleClick() 双击
  • dragAndDrop() 拖动
  • release() 释放鼠标
  • perform() 执行所有Actions中存储的行为
// 新建一个action   
Actions action = new Actions(driver);   
// 鼠标左键单击
action.click().perform();
// 鼠标左键双击
action.doubleClick(WebElement).perform();
// 鼠标左键按下
action.clickAndHold(WebElement).perform();
// 鼠标移动到元素
action.moveToElement(WebElement).perform();
// 元素右键点击
action.contextClick(WebElement).perform();
// 将目标元素拖拽到指定的元素上
action.dragAndDrop(webElement1,webElement2);
action.dragAndDrop(webElement, xOffset, yOffset);

Actions action = new Actions(driver);
action.keyDown(Keys.CONTROL);//按下control键
action.keyUp(Keys.CONTROL);//松开control键
action.keyDown(Keys.CONTROL).keyDown(Keys.ALT).keyDown("A").keyUp(Keys.CONTROL).keyUp(Keys.ALT).keyUp("A").perform();
action.sendKeys(Keys.CONTROL+"a").perform();
action.sendKeys(Keys.CONTROL, Keys.ALT, "A").perform();
2.5.2 元素sendKeys()
sendKeys(Keys.BACK_SPACE) 回格键(BackSpace)
sendKeys(Keys.SPACE) 空格键(Space)
sendKeys(Keys.TAB) 制表键(Tab)

2.6 窗口控制

2.6.1 窗口切换

使用 driver.getWindowHandles() 方法获取所有窗口

使用 driver.switchTo().window(hand) 切换窗口

Set<String> handles = driver.getWindowHandles();
for (String hand : handles) {
    if (!StringUtils.equals(mainHand, hand)) {
        driver.switchTo().window(hand);
    }
}

3 linux无窗口模式

3.1 linux安装chrome浏览器

wget https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm 
yum install -y google-chrome-stable_current_x86_64.rpm

3.2 下载对应版本的driver

查询当前浏览器版本

google-chrome --version

avatar

3.3 设置Selenium无头模式

  1. 设置无头模式
options.setHeadless(Boolean.TRUE);
  1. 配置头信息
options.addArguments("--no-sandbox");
options.addArguments("--disable-dev-shm-usage");
  1. 需要配置浏览器窗口大小,来确保元素可以检索
WebDriverWait wait = new WebDriverWait(driver, 60);
Dimension dimension = new Dimension(1920, 1080);
driver.manage().window().setSize(dimension);
  1. 若遇到如下提示
The driver is not executable: /opt/code/news/chromedriver

运行如下命令即可:

chmod 775 ./chromedriver

3.4 设置成功,启动运行





更多好玩好看的内容,欢迎到我的博客交流,共同进步        WaterMin

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java使用Selenium实现自动化测试以及全功能爬虫 的相关文章

  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • 获取文件的总大小(以字节为单位)[重复]

    这个问题在这里已经有答案了 可能的重复 java 高效获取文件大小 https stackoverflow com questions 116574 java get file size efficiently 我有一个名为 filenam
  • 无法导入 langchain.agents.load_tools

    我正在尝试使用 LangChain Agents 但无法导入 load tools 版本 langchain 0 0 27 我尝试过这些 from langchain agents import initialize agent from
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • Django 视图中的“请求”是什么

    在 Django 第一个应用程序的 Django 教程中 我们有 from django http import HttpResponse def index request return HttpResponse Hello world
  • 将 Matlab 的 datenum 格式转换为 Python

    我刚刚开始从 Matlab 迁移到 Python 2 7 在读取 mat 文件时遇到一些问题 时间信息以 Matlab 的日期数字格式存储 对于那些不熟悉它的人 日期序列号将日历日期表示为自固定基准日期以来已经过去的天数 在 MATLAB
  • Python GTK+ 画布

    我目前正在通过 PyGobject 学习 GTK 需要画布之类的东西 我已经搜索了文档 发现两个小部件似乎可以完成这项工作 GtkDrawingArea 和 GtkLayout 我需要一些基本函数 如 fillrect 或 drawline
  • 找到一个数字所属的一组范围

    我有一个 200k 行的数字范围列表 例如开始位置 停止位置 该列表包括除了非重叠的重叠之外的所有类型的重叠 列表看起来像这样 3 5 10 30 15 25 5 15 25 35 我需要找到给定数字所属的范围 并对 100k 个数字重复该
  • 在 Google App Engine 中,如何避免创建具有相同属性的重复实体?

    我正在尝试添加一个事务 以避免创建具有相同属性的两个实体 在我的应用程序中 每次看到新的 Google 用户登录时 我都会创建一个新的播放器 当新的 Google 用户在几毫秒内进行多个 json 调用时 我当前的实现偶尔会创建重复的播放器
  • 如何使用 AWS Lambda Python 读取 AWS S3 存储的 Word 文档(.doc 和 .docx)文件内容?

    我的场景是 我尝试使用 python 实现从 Aws Lambda 读取 AWS 存储的 S3 word 文档 doc 和 docx 文件内容 下面的代码是我使用的 我的问题是我可以获取文件名 但无法读取内容 def lambda hand
  • python 中的“槽包装器”是什么?

    object dict 和其他地方的隐藏方法设置为这样的
  • Python:Goslate 翻译请求返回“503:服务不可用”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我们不允许提出寻求书籍 工具 软件库等推荐的问题 您可以编辑问题 以便用事实和引文来回答 这个问题似乎不是关于主要由程序员使用的特定编程问
  • 如何以正确的方式为独立的Python应用程序制作setup.py?

    我读过几个类似的主题 但还没有成功 我觉得我错过或误解了一些基本的事情 这就是我失败的原因 我有一个用 python 编写的 应用程序 我想在标准 setup py 的帮助下进行部署 由于功能复杂 它由不同的 python 模块组成 但单独
  • 每当使用 import cv2 时 OpenCV 都会出错

    我在终端上使用 pip3 install opencv contrib python 安装了 cv2 并且它工作了 但是每当我尝试导入 cv2 或运行导入了 cv2 的 vscode 文件时 在 python IDLE 上它都会说 Trac
  • 使用反射覆盖最终静态字段是否有限制?

    在我的一些单元测试中 我在最终静态字段上的反射中遇到了奇怪的行为 下面是说明我的问题的示例 我有一个基本的 Singleton 类 其中包含一个 Integer public class BasicHolder private static
  • 在virtualenv中下载sqlite3

    我正在尝试使用命令创建应用程序python3 manage py startapp webapp但我收到一条错误消息 django core exceptions ImproperlyConfigured 加载时出错 pysqlite2 或
  • 如何在 Flask 中的视图函数/会话之间传递复杂对象

    我正在编写一个 Web 应用程序 当 且仅当 用户登录时 该应用程序从第三方服务器接收大量数据 这些数据被解析为自定义对象并存储在list 现在 用户在应用程序中使用这些数据 调用不同的视图 例如发送不同的请求 我不确定什么是最好的模式在视
  • 使用 svn 1.8.x、subclise 1.10 的 m2e-subclipse 连接器在哪里?

    我读到 m2e 的生产商已经停止生产 svn 1 7 以外的任何版本的 m2e 连接器 Tigris 显然已经填补了维护 m2e subclipse 连接器的空缺 Q1 我的问题是 使用 svn 1 8 x 的 eclipse 更新 url
  • 如果没有抽象成员,基类是否应该标记为抽象?

    如果一个类没有抽象成员 可以将其标记为抽象吗 即使没有实际理由直接实例化它 除了单元测试 是的 将不应该实例化的基类显式标记为抽象是合理且有益的 即使在没有抽象方法的情况下也是如此 它强制执行通用准则来使非叶类抽象 它阻止其他程序员创建该类

随机推荐

  • w10计算机怎么恢复出厂设置路由器,技术编辑为你解决win10系统打不开192.168.1.1设置界面的还原步骤...

    很多人都懂一些简单的电脑系统问题的解决方案 但是win10系统打不开192 168 1 1设置界面的情况 想必大家都遇到过win10系统打不开192 168 1 1设置界面的情况吧 那么应该怎么处理win10系统打不开192 168 1 1
  • 【SQL】5 SQL SELECT DISTINCT 语句

    SELECT DISTINCT 语句用于返回唯一不同的值 SQL SELECT DISTINCT 语句 在表中 一个列可能会包含多个重复值 有时您也许希望仅仅列出不同 distinct 的值 DISTINCT 关键词用于返回唯一不同的值 S
  • Vue 中如何实现监测数组变化

    vue中响应式数据的原理是通过Object defineProperty控制getter和setter 并利用观察者模式完成的响应式设计 数组考虑性能原因没有用defineProperty对数组的每一项进行拦截 而是选择重写数组api方法
  • git提交忽略文件名称大小写问题解决

    在项目开发中 关于文件名称大小写的修改 项目可能会默认忽略 对于一开始就新建的文件名问题不大 1 git在提交代码时 会忽略文件名称大小写 导致本地代码与远程代码不一致 此时可利用终端指令来检查下 git config get core i
  • 机械臂 手眼标定 手眼矩阵 eye-in-hand 原理、实践及代码

    1 手眼标定 所谓手眼系统 就是人眼睛看到一个东西的时候要让手去抓取 就需要大脑知道眼睛和手的坐标关系 而相机知道的是像素坐标 机械手是空间坐标系 所以手眼标定就是得到像素坐标系和空间机械手坐标系的坐标转化关系 目前工业上通常使用两种方法进
  • IDEA下导入maven项目时Maven Project处未能显示jar包正常解决办法

    IDEA下导入多级maven项目时未能显示正常解决办法 1 Ctrl Alt Shift S 打开Project Structrue 2 左边点击 Modules 切换到Modules选项卡 3 此时你如果发现现在已经加载所有工程中并没有你
  • IPSEC流程例子及两个阶段的协商过程详细介绍

    IPSEC VPN两个阶段的协商过程详细介绍 IPSec体系结构模型图 我们来看一个完整的IPSec体系结构模型图 以便更好地理解IPSec体系结构 IPSec流程图 SAKMP IKE第一阶段称为ISAKMP IKE的管理连接阶段 使用双
  • docker中镜像和容器的批量操作

    1 批量删除镜像 docker rmi docker images grep 条件 awk print 3 docker images 所展示的列表 第三列为镜像id 根据镜像id做删除操作 2 批量删除容器 docker rm f doc
  • 华为OD机试 - 最长广播响应(Java)

    题目描述 某通信网络中有N个网络结点 用1到N进行标识 网络中的结点互联互通 且结点之间的消息传递有时延 相连结点的时延均为一个时间单位 现给定网络结点的连接关系link i u v 其中u和v表示网络结点 当指定一个结点向其他结点进行广播
  • 因果推断(四)——后门调整、前门调整、逆概率加权

    在因果推断 三 中 我们介绍了干预的相关概念 在本文中 我们对一些方法进行介绍 这些方法可用于利用干预分析变量之间的因果关系 在因果推断 三 中 我们得出了调整公式 如上式 假设PA为A节点的所有父节点的集合 则上 式可以修改为 其中b为P
  • 架构与思维:系统容量设计

    背景 单位每年都会举行运动会 有一个2000m长跑的项目 大约每年报名人员为男选手40人 女选手20人 只有一条橡胶跑道 一次比赛10人齐跑 所以至少需要6场比赛 2000米的完成时间要求是20分钟 超过20分钟不计数 所以比赛耗时我们计算
  • Multi-Scale Convolutional Neural Networks for Time Series Classification

    keywords 时间序列处理 深度学习 keras 针对现有时间序列分类方法的特征提取与分类过程分离 且无法提取存在于不同时间尺度序列的不同特征的问题 作者提出MCNN模型 对于单一时间序列输入 进行降采样和滑动平均等变化 产生多组长度不
  • 双向dc-dc变换器原理

    buck电路原理 电容用于平滑电压 由于电容电压不能突变 所以再接一个电感 二极管的作用是给电感提供续流作用 boost电路原理 由于直接升压难以实现 理想情况下输入输出功率相同 可以通过减小输出电流来实现提高输出电压 双向dc dc变换器
  • Open3D 格网法计算点云的占地面积

    目录 一 算法原理 二 代码实现 三 结果展示 四 测试数据 一 算法原理 该方法主要用于粗略统计机载点云的占地面积 方法原理是将点云沿 X O Y XOY XOY面划分成格网 统计有点的格网面积来近似表示点云占地面积 二 代码实现
  • Android 加载高清巨图,无需剪裁压缩

    LargeImage Android 加载大图 可以高清显示10000 10000像素的图片 可以滑动 放大缩小具有PhotoView的效果 普通图片也可以用它展示 Gradle compile com shizhefei LargeIma
  • ospf协议域内SPF算法计算生成树的理解

    在阅读华为IERS文档后的有关SPF的理解 有些详细原理细节省略 图片来自华为文档 计算域内生成树使用Dijkstra算法计算最短路径 使用如下的拓扑图 OSPF的LSA有七种类型 SPF算法计算最小生成树使用一类Router LSA和二类
  • Spark编程基础-RDD

    目录 1 何为RDD 2 RDD的五大特性 3 RDD常用算子 3 1 Transformation算子 1 map 2 flatMap 3 reduceByKey 4 mapValues 5 groupBy 6 filter 7 dist
  • CentOS7 上安装 Postgresql

    1 选择安装包 在postgresql的官方即可找到源码文件目录 地址如下 postgresql的官网地址 根据项目需求选择对应的版本进行安装 具体如下图所示 2 安装 解压安装包 首先进入源码包所在的目录进行解压 root admin n
  • 【http】get/post 获取请求参数

    1 只对 get 请求获取 Url 后面的参数 使用 HttpServletRequest的 getQueryString 方法 String getQueryString 2 无论是 get 还是 post 请求 获取参数 使用 Serv
  • Java使用Selenium实现自动化测试以及全功能爬虫

    1 你听没听说过Selenium 1 1 自动化测试 提到Selenium 便离不开自动化测试 自动化测试 就是把手工进行的测试过程 转变成机器自动执行的测试过程 自动化测试有如下优点 对程序的回归测试更方便 这可能是自动化测试最主要的任务