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 {
    @SneakyThrows
    public static void main(String[] args) {
        // 设置 ChromeDriver 的路径
        System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe");

        // 配置 ChromeOptions
        ChromeOptions 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 {
            // 访问指定的 URL
            driver.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");
        // 初始化WebDriver
        WebDriver 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");

    // 配置 ChromeOptions
    ChromeOptions 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. 效果见演示视频

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文阅读 - TIME-LLM: TIME SERIES FORECASTING BY REPROGRAMMING LARGE LANGUAGE MODELS

论文链接&#xff1a; https://arxiv.org/abs/2310.01728 目录 摘要 1 INTRODUCTION 2 RELATED WORK 3 METHODOLOGY 3.1 MODEL STRUCTURE 4 MAIN RESULTS 4.1 长期预测 4.2 短期预测 4.3 FEW-SHOT FORECASTING 5 CONCLUSION AND FUTURE WORK 摘要 动机&#xff1a; 时…

黎加厚教授:生成式人工智能对课程教材教法的影响

01 生成式人工智能与过去的信息技术有哪些不一样的地方 2023年&#xff0c;生成式人工智能&#xff08;GenAI&#xff09;犹如百年惊雷&#xff0c;改变了我对计算机的认识。最先让我折服的是AI绘画&#xff0c;我只需要把心中想象的场景用提示词详细描述&#xff0c;立刻就生…

VS code 无法go to以及全局搜索不到问题

一、无法goto问题 需要安装插件C/C。 安装完成后&#xff0c;检查设置是否生效。步骤如下&#xff1a; 1. 点开设置&#xff1a; 2. 搜索c/c查找引擎&#xff0c;确认其为默认值&#xff0c;即可。 二、全局搜索不到 VS code有时候全局搜索内容&#xff0c;搜索不到或者搜索…

基于51单片机的汽车智能灯光控制系统

一.硬件方案 本设计硬件部分&#xff0c;中央处理器采用了STC89C52RC单片机&#xff0c;另外使用两个灯珠代表远近光灯&#xff0c;感光部分采用了光敏电阻&#xff0c;因为光敏电阻输出的是电压模拟信号&#xff0c;单片机不能直接处理模拟信号&#xff0c;所以经过ADC0832进…

C语⾔:内存函数

1. memcpy使⽤和模拟实现&#xff08;对内存块的复制&#xff0c;不在乎类型&#xff09; void * memcpy ( void * destination, const void * source, size_t num ); • 函数memcpy从source的位置开始向后复制num个字节的数据到destination指向的内存位置。 • 这个函数在遇…

卷积神经网络实现手写数字识别 pytorch

卷积神经网络实现手写数字识别 导入相关的库 import torch import torch.nn as nn from torch.autograd import Variable import torch.utils.data as Data import torchvision import matplotlib.pyplot as plt设置相应的超参数 EPOCH1 BATCH_SIZE50 LR0.001 DOWNLOAD_MNIS…

将 KNX 接入 Home Assistant 之二 准备软件

写在前面&#xff1a; 在KNX官网也有关于 Home Assistant 的教程&#xff0c;地址是 Get started with Home Assistant x KNX 需要的东西是 a KNX IP Interface or Routera Raspberry Pian SD Card at least 32 GB 安装 Home Assistant 系统 下载镜像&#xff1a; 地址&…

网络原理-HTTPS协议

在前面说到HTTP中,我们通过抓包,可以看到许多信息内容,其中往往会包含一些敏感信息,这些都是明文传输,当我们的请求被黑客或者不法分子截获后,那就很危险了,因此衍生出了HTTPS协议来对传输数据进行加密。 一、加密原理 基本原理如下&#xff1a; 明文 密钥 > 密文 密文…

【每日刷题】Day50

【每日刷题】Day50 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 654. 最大二叉树 - 力扣&#xff08;LeetCode&#xff09; 2. 119. 杨辉三角 II - 力扣&#xff08…

Gitlab不允许使用ssh拉取代码的解决方案

一、起因 之前一直是用ssh进行代码拉取&#xff0c;后来公司搞网安行动&#xff0c;不允许ssh进行连接拉取代码了 因为我是用shell写了个小型的CI/CD,部署前端项目用于后端联调的&#xff0c;因此在自动部署时&#xff0c;不方便人机交互&#xff0c;所以需要自动填充账密。 …

如何在群晖NAS安装WPS Office并使用公网地址远程访问处理文档表格

前言 作者简介&#xff1a; 懒大王敲代码&#xff0c;计算机专业应届生 今天给大家聊聊如何在群晖NAS安装WPS Office并使用公网地址远程访问处理文档表格&#xff0c;希望大家能觉得实用&#xff01; 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&a…

水电自动抄表系统是什么?

1.简述&#xff1a;水电自动抄表系统 水电自动抄表系统是一种现代化计量检定解决方法&#xff0c;为提升公用事业服务项目的效率和精确性。传统式手动抄水表方法已经被这类高效率、精准的自动化系统所替代&#xff0c;它能够实时、远程控制地收集解决水电使用数据。 2.系统原…

列表、元组、字典和集合的区别

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在前面介绍了序列中的列表、元组、字典和集合的应用&#xff0c;下面通过表2对这几个数据序列进行比较。 表2 列表、元组、字典和集合的区别 数 据…

【算法】dd爱转转

✨题目链接&#xff1a; dd爱旋转 ✨题目描述 读入一个n∗n的矩阵&#xff0c;对于一个矩阵有以下两种操作 1:顺时针旋180 2:关于行镜像 如 变成 给出q个操作&#xff0c;输出操作完的矩阵 ✨输入描述: 第一行一个数n(1≤n≤1000)&#xff0c;表示矩阵大小 接下来n行&#xff…

【全开源】优校管理系统支持微信小程序+微信公众号+H5

概述 优校管理系统(简称优校管)是基于FastAdmin和ThinkPHP进行开发的中小学信息化管理系统&#xff0c;拥有PC版、UniAPP版(高级授权)。支持微信小程序、H5等多平台&#xff0c;主要用于信息管理、教学管理、素养评价&#xff0c;支持多个学校(标准授权限5个&#xff0c;高级授…

Nat Genet|马丁院士团队利用单细胞和空间多组学描绘宫颈鳞癌免疫微环境图谱

宫颈鳞状细胞癌&#xff08;CSCC&#xff09;是宫颈癌最常见的组织学类型。虽然局部疾病预后良好&#xff0c;但晚期、转移性或复发性CSCC的5年生存率仅为16.5%&#xff0c;晚期宫颈癌中对免疫检查点阻断的反应有限。细胞异质性和可塑性是肿瘤进展和肿瘤免疫微环境(TIME)调节的…

自由应用大本营?开源免费的Android应用商店:F-Droid Client

F-Droid Client&#xff1a;拥抱开源&#xff0c;守护隐私&#xff0c;让自由软件成为您生活的一部分- 精选真开源&#xff0c;释放新价值。 概览 F-Droid Client是一个开源的Android应用商店&#xff0c;它在GitHub上免费提供。这个项目致力于收集和展示各类自由及开源软件&a…

响应式流和reactor框架进阶

响应式流和reactor框架进阶 响应式流创建、转换、处理 本文档主要介绍在响应式编程中如何从流中获取数据并处理。 前提条件 假设您已经能掌握Java基础、Maven使用、Lamda表达式、响应式编程等基础。 如何获取流中数据 &#x1f30f; 说明 1、不要试图从流中获取数据出来&a…

牛客NC391 快乐数【simple 模拟法 Java/Go/PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/293b9ddd48444fa493dd17da0feb192d 思路 直接模拟即可Java代码 import java.util.*;public class Solution {/*** 代码中的类名、方法名、参数名已经指定&#xff0c;请勿修改&#xff0c;直接返回方法规定的值…

自动化测试和手动测试相比,哪个更具优势?

自动化测试和手动测试都是软件测试中常用的两种方法&#xff0c;它们在不同的场景下具有不同的优势。下面将从各个角度进行详细的比较&#xff0c;以帮助读者更好地了解两种方法。 1. 效率 自动化测试相对于手动测试具有更高的效率。手动测试需要人工操作执行测试步骤、输入测…