java + selemuim 自动化 实现监听网页窗口组件和事件,完成登录和“防挂机”
下载chrome浏览器
有win、mac系统的历史版本:
链接:https://vikyd.github.io/download-chromium-history-version/#
下载chrome driver
知道了Chrome浏览器的版本号,就可以开始下载相应版本的ChromeDriver了
淘宝镜像:https://registry.npmmirror.com/binary.html?path=chromedriver/
官方镜像:https://sites.google.com/a/chromium.org/chromedriver/downloads
这里建议用淘宝镜像
找到对应自己chrome对应的版本号
下载对应自己系统的驱动压缩包
安装chrome driver
第一步:把驱动压缩包解压后放到浏览器安装目录下:
第二步:配置环境变量
以下是几个常见操作系统的环境变量设置位置:
Windows:控制面板 -> 系统和安全 -> 系统 -> 高级系统设置 -> 环境变量。
macOS:在终端中输入“nano ~/.bash_profile”来编辑bash profile文件。
Linux:在终端中输入“nano ~/.bashrc”来编辑bashrc文件
我的是window 11本,所以 此电脑>属性>高级系统设置>环境变量
验证安装
window : cmd 打开 dos窗口 :输入: chromedriver 回车;
证明安装成功,到这里准备工作就结束了!
代码实现
第一步:引入 pom
<dependencies>
<!-- 发送 HTTP 请求 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.32</version>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version> <!-- 替换为你实际使用的 Log4j 版本 -->
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.14.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>compile</scope>
</dependency>
</dependencies>
第二步:核心代码块
private static String checkDivText = "已触发防挂机验证,请点击“继续学习”.......";
private static String checkButtonText = "继续学习....";
private static String checkStartButtonText = "开始学习....";
private static String userName = "your-username";
private static String isCheckCompleteUrl = "your-listenter-url";
private static String password = "your-password";
private static String commentUrl = "《complate-auto-comment-url-to-score》";
private static boolean commentFlag = false;
public static void cheatStudyV2(String kngId) throws InterruptedException {
// 设置 Chrome 驱动程序路径
System.setProperty("webdriver.chrome.driver", "C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");
String url = "课程地址";
// 创建 ChromeOptions 对象
ChromeOptions options = new ChromeOptions();
// 创建一个ChromeDriver实例,传入ChromeOptions
WebDriver driver = new ChromeDriver(options);
// 导航到目标页面"C:\Users\l\Desktop\test.html"
driver.get(url);
//休眠等待一下,避免网页还没渲染完就去找组件,可能会导致 找不到组件而空指针
Thread.sleep(8000);
//因为网页是要先登录的,就要先抓登录页 的用户名和密码框 ,实现自动登录
List<WebElement> usernameList = driver.findElements(By.name("username"));
usernameList.get(0).sendKeys(userName);
WebElement passwordElement = driver.findElement(By.cssSelector("input[type='password']"));
passwordElement.sendKeys(password);
WebElement checkbox = driver.findElements(By.id("secretProtocol")).get(1);
boolean isChecked = checkbox.isSelected();
if (!isChecked) {
checkbox.click();
}
List<WebElement> loginButtonList = driver.findElements(By.cssSelector("button[type='button']"));
loginButtonList.get(2).click();
Thread.sleep(5000);
List<WebElement> buttonStuFirstList = driver.findElements(By.className("yxtf-button--larger"));
log.info("【1.0】第一次进入会弹出【继续学习or开始学习】按钮,捕获到 相关 class:【{yxtf-button--larger}】的数量为:{}", buttonStuFirstList.size());
if (!CollectionUtils.isEmpty(buttonStuFirstList)) {
buttonStuFirstList=buttonStuFirstList.stream().filter(s -> s.getText().equals(checkButtonText)).collect(Collectors.toList());
if(!CollectionUtils.isEmpty(buttonStuFirstList)){
WebElement buttonStuFirst = buttonStuFirstList.get(0);
buttonStuFirst.click();
log.info("【2.0 success】成功点击,初次进入后的【继续学习】按钮");
}else{
buttonStuFirstList = driver.findElements(By.className("yxtf-button--larger"));
buttonStuFirstList=buttonStuFirstList.stream().filter(s -> s.getText().equals(checkStartButtonText)).collect(Collectors.toList());
if(!CollectionUtils.isEmpty(buttonStuFirstList)) {
WebElement buttonStuFirst = buttonStuFirstList.get(0);
buttonStuFirst.click();
log.info("【2.0 success】成功点击,初次进入后的【开始学习】按钮");
}
}
}
int count = 0;
// 定时抓取div并点击按钮,也可以不用 定时,自己通过页面弹窗状态进行判断是否进行下一步
while (true) {
List<WebElement> divElementList1 = driver.findElements(By.className("color-gray-9"));
divElementList1 = divElementList1.stream().filter(s -> s.getText().equals(checkDivText)).collect(Collectors.toList());
if (!CollectionUtils.isEmpty(divElementList1)) {
WebElement checkDiv = divElementList1.get(0);
if (checkDiv != null) {
Thread.sleep(1000);
log.info("【2.0】检测到 继续学习弹窗已弹出");
List<WebElement> submitButtonList = driver.findElements(By.className("yxtf-button--large"));
for (WebElement t : submitButtonList) {
log.info("【2.1】:获取 继续学习弹窗 到的 集合为:{}", t.getText());
}
WebElement submitButton = null;
submitButtonList = submitButtonList.stream().filter(s -> s.getText().equals(checkButtonText)).collect(Collectors.toList());
if (submitButtonList == null) {
continue;
}
try {
submitButton = submitButtonList.get(0);
submitButton.click();
count = 0;
log.info("【3.0 success】成功点击,防挂机弹窗中的【继续学习】按钮,count重置");
} catch (IndexOutOfBoundsException e) {
Thread.sleep(5000);
continue;
}
} else {
count++;
log.info("【4.0】未找到对应的【yxtf-button--large】的【继续学习】的 button,进入 等待,次数:{}", count);
Thread.sleep(60 * 1000);
}
} else {
count++;
log.info("【5.0】未找到对应的【color-gray-9】的 【弹窗】 div,进入 等待次数:{}", count);
Thread.sleep(60 * 1000);
}
if (count >= 10) {
log.info("【5.1】 已10分钟未响应,进行检测是否此课程已学习完成!!!");
if (HttpUtil.checkComplete(null, kngId)) {
log.info("【6.6.6】 此课程已学习完毕!!!");
// 关闭浏览器实例
driver.quit();
break;
} else {
count = 7;
}
}
}
}
然后就结束了,直接启动运行,就可以了!全程自动化操作。
开启后浏览器不要最小化,最小化会导致监听不到!!!
对对对!!!有人第一次启动运行能可能会抛这个异常:
这是 chrome和driver 版本不一致导致的。换个 版本就好。