修复播放第二个视频时,由于视频未处于视图中导致无法读取播放进度的问题;
添加了"智慧树"平台的自动化实现,目前已实现视频播放、文件浏览等必要功能,答题模块暂未实现
This commit is contained in:
84
dependency-reduced-pom.xml
Normal file
84
dependency-reduced-pom.xml
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>work.slhaf</groupId>
|
||||
<artifactId>CxstudyAuto</artifactId>
|
||||
<version>1.0</version>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>work.slhaf.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer>
|
||||
<mainClass>work.slhaf.Main</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>hamcrest-core</artifactId>
|
||||
<groupId>org.hamcrest</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<properties>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
</project>
|
||||
81
pom.xml
81
pom.xml
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>work.slhaf</groupId>
|
||||
<artifactId>CxstudyAuto</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.0</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
@@ -43,7 +43,7 @@
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
<scope>provided</scope>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
@@ -57,16 +57,6 @@
|
||||
<version>4.13.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!--<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>htmlunit-driver</artifactId>
|
||||
<version>4.13.0</version>
|
||||
</dependency>-->
|
||||
<!--<dependency>
|
||||
<groupId>net.sourceforge.htmlunit</groupId>
|
||||
<artifactId>htmlunit</artifactId>
|
||||
<version>2.70.0</version>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
@@ -75,4 +65,71 @@
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- 1. 让 Maven 知道主类 -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>work.slhaf.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- 2. 确保 Lombok 处理 @Slf4j -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<source>21</source>
|
||||
<target>21</target>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.36</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- 3. 生成可执行 JAR(打包所有依赖) -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>work.slhaf.Main</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -3,23 +3,48 @@ package work.slhaf;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import work.slhaf.config.Config;
|
||||
import work.slhaf.task.CxstudyTask;
|
||||
import work.slhaf.task.ZhsTask;
|
||||
import work.slhaf.util.AiUtil;
|
||||
import work.slhaf.util.OcrUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
|
||||
@Slf4j
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws InterruptedException, IOException {
|
||||
Config config = Config.load();
|
||||
if (config.isAiEnable()){
|
||||
if (config.isAiEnable()) {
|
||||
AiUtil.load(config.getAiConfig());
|
||||
OcrUtil.load(config.getOcrConfig());
|
||||
}
|
||||
|
||||
Scanner scanner = new Scanner(System.in);
|
||||
int target;
|
||||
String notice = """
|
||||
1. 学习通
|
||||
2. 智慧树
|
||||
""";
|
||||
System.out.println(notice);
|
||||
while (true) {
|
||||
System.out.print("选择目标平台(输入序号): ");
|
||||
target = scanner.nextInt();
|
||||
switch (target) {
|
||||
case 1:
|
||||
CxstudyTask cxstudyTask = CxstudyTask.initialize(config);
|
||||
cxstudyTask.run();
|
||||
break;
|
||||
case 2:
|
||||
ZhsTask zhsTask = ZhsTask.initialize(config);
|
||||
zhsTask.run();
|
||||
break;
|
||||
default:
|
||||
log.info("输入目标平台对应的序号!");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,9 +18,10 @@ public class Config {
|
||||
private String browser;
|
||||
private boolean aiEnable;
|
||||
private boolean headless;
|
||||
private CxstudyConfig cxstudyConfig;
|
||||
private OcrConfig ocrConfig;
|
||||
private AiConfig aiConfig;
|
||||
private CxstudyConfig cxstudyConfig;
|
||||
private ZhsConfig zhsConfig;
|
||||
|
||||
private Config() {
|
||||
}
|
||||
@@ -61,7 +62,7 @@ public class Config {
|
||||
}
|
||||
|
||||
System.out.println("\r\n---------------\r\n");
|
||||
System.out.println("是否显示GUI界面?第一次运行建议选择显示,测试没有问题后,再修改配置文件为隐藏GUI界面");
|
||||
System.out.println("是否启用无头模式(不显示GUI界面)?第一次运行建议选择禁用,测试没有问题后,再修改配置文件为启用无头模式");
|
||||
System.out.print("输入 y (启用) 或 n (禁用) : ");
|
||||
String headlessStr = "";
|
||||
boolean headless;
|
||||
@@ -118,10 +119,17 @@ public class Config {
|
||||
System.out.print("目标课程: ");
|
||||
studyConfig.setTarget(sc.nextLine());
|
||||
|
||||
System.out.println("\r\n---------------\r\n");
|
||||
ZhsConfig zhsConfig = new ZhsConfig();
|
||||
System.out.println("记录智慧树配置(智慧树账号需绑定qq, 将通过qq登录): ");
|
||||
System.out.print("目标课程: ");
|
||||
zhsConfig.setTarget(sc.nextLine());
|
||||
|
||||
System.out.println("\r\n---------------\r\n");
|
||||
config.cxstudyConfig = studyConfig;
|
||||
config.ocrConfig = ocrConfig;
|
||||
config.aiConfig = aiConfig;
|
||||
config.zhsConfig = zhsConfig;
|
||||
String configStr = JSONUtil.toJsonPrettyStr(config);
|
||||
System.out.println("配置文件如下: \r\n" + configStr);
|
||||
System.out.println("配置文件将位于: "+file.getAbsolutePath());
|
||||
|
||||
18
src/main/java/work/slhaf/config/ZhsConfig.java
Normal file
18
src/main/java/work/slhaf/config/ZhsConfig.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package work.slhaf.config;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ZhsConfig {
|
||||
private String target = "";
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return """
|
||||
ZshConfig:
|
||||
target: %s
|
||||
""".formatted(target);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package work.slhaf.exception;
|
||||
|
||||
public class TargetClassNotFoundException extends RuntimeException {
|
||||
public TargetClassNotFoundException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package work.slhaf.exception;
|
||||
|
||||
public class UnknownTaskPointException extends RuntimeException {
|
||||
public UnknownTaskPointException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,10 @@
|
||||
package work.slhaf.task;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openqa.selenium.*;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.openqa.selenium.edge.EdgeDriver;
|
||||
import org.openqa.selenium.edge.EdgeOptions;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
@@ -19,6 +12,7 @@ import work.slhaf.config.Config;
|
||||
import work.slhaf.exception.AiRequestException;
|
||||
import work.slhaf.exception.AiResponseFormatException;
|
||||
import work.slhaf.exception.OcrRequestException;
|
||||
import work.slhaf.exception.TargetClassNotFoundException;
|
||||
import work.slhaf.pojo.answer.Answer;
|
||||
import work.slhaf.pojo.answer.MultiChoiceAnswer;
|
||||
import work.slhaf.pojo.answer.SingleChoiceAnswer;
|
||||
@@ -29,6 +23,7 @@ import work.slhaf.pojo.question.SingleChoiceQuestion;
|
||||
import work.slhaf.pojo.question.TextQuestion;
|
||||
import work.slhaf.util.AiUtil;
|
||||
import work.slhaf.util.OcrUtil;
|
||||
import work.slhaf.util.TaskUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
@@ -93,14 +88,14 @@ public class CxstudyTask {
|
||||
toBeFinished = getTodoTasks();
|
||||
}
|
||||
|
||||
log.info("作答完毕!");
|
||||
log.info("任务完成!");
|
||||
driver.quit();
|
||||
break;
|
||||
}catch (AiRequestException | OcrRequestException e) {
|
||||
} catch (AiRequestException | OcrRequestException e) {
|
||||
log.error(e.getMessage());
|
||||
driver.quit();
|
||||
break;
|
||||
}catch (WebDriverException e) {
|
||||
} catch (WebDriverException e) {
|
||||
log.error("\r\n---------------\r\n");
|
||||
log.error(e.getLocalizedMessage());
|
||||
log.error("\r\n---------------\r\n");
|
||||
@@ -108,24 +103,22 @@ public class CxstudyTask {
|
||||
driver.get("https://i.chaoxing.com/");
|
||||
Thread.sleep(5000);
|
||||
switchPage();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void handleDocTask(int i) throws InterruptedException {
|
||||
try {
|
||||
driver.switchTo().frame(i).switchTo().frame(2);
|
||||
log.info("开始处理文档浏览...");
|
||||
long lastHeight = (long) executor.executeScript("return document.body.scrollHeight;");
|
||||
long currentHeight = 0;
|
||||
double lastHeight = (double) executor.executeScript("return document.body.scrollHeight;");
|
||||
double currentHeight = 0;
|
||||
int step = 2000;
|
||||
while (currentHeight < lastHeight) {
|
||||
executor.executeScript("window.scrollBy(0, arguments[0]);", step);
|
||||
Thread.sleep(600);
|
||||
currentHeight = (long) executor.executeScript("return window.scrollY + window.innerHeight;");
|
||||
lastHeight = (long) executor.executeScript("return document.body.scrollHeight;");
|
||||
currentHeight = (double) executor.executeScript("return document.body.scrollHeight;");
|
||||
lastHeight = (double) executor.executeScript("return document.body.scrollHeight;");
|
||||
}
|
||||
log.info("文档浏览任务完成!");
|
||||
} catch (WebDriverException ignored) {
|
||||
@@ -314,6 +307,7 @@ public class CxstudyTask {
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(".//div[@class='prev_video_left']")));
|
||||
log.info("开始处理视频播放...");
|
||||
WebElement play = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class='vjs-big-play-button']")));
|
||||
executor.executeScript("arguments[0].scrollIntoView({behavior: 'auto', block: 'center'})", play);
|
||||
Thread.sleep(2000);
|
||||
play.click();
|
||||
WebElement video = driver.findElement(By.id("video_html5_api"));
|
||||
@@ -342,13 +336,13 @@ public class CxstudyTask {
|
||||
int offsetY = (int) (Math.random() * step) - step / 2; // 随机上下移动
|
||||
try {
|
||||
actions.moveByOffset(offsetX, offsetY).perform();
|
||||
}catch (Exception e) {
|
||||
} catch (Exception e) {
|
||||
actions.moveToElement(video, startX, startY).perform();
|
||||
}
|
||||
Thread.sleep(200);
|
||||
}
|
||||
String currentTime = driver.findElement(By.xpath(".//span[@class='vjs-current-time-display']")).getText();
|
||||
if (currentTime.isEmpty()){
|
||||
if (currentTime.isEmpty()) {
|
||||
actions.moveToElement(video, startX, startY).perform();
|
||||
currentTime = driver.findElement(By.xpath(".//span[@class='vjs-current-time-display']")).getText();
|
||||
}
|
||||
@@ -407,12 +401,17 @@ public class CxstudyTask {
|
||||
Thread.sleep(5);
|
||||
try {
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@name='课程']"))).click();
|
||||
}catch (TimeoutException e){
|
||||
} catch (TimeoutException e) {
|
||||
driver.findElement(By.xpath("//div[@name='课程']")).click();
|
||||
}
|
||||
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(0));
|
||||
String xpath = ".//span[@title='" + targetClassName + "']";
|
||||
String targetClassHref = wait.until(ExpectedConditions.elementToBeClickable(By.xpath(xpath))).findElement(By.xpath("..")).getDomAttribute("href");
|
||||
String targetClassHref;
|
||||
try {
|
||||
targetClassHref = wait.until(ExpectedConditions.elementToBeClickable(By.xpath(xpath))).findElement(By.xpath("..")).getDomAttribute("href");
|
||||
}catch (Exception e){
|
||||
throw new TargetClassNotFoundException("未找到课程: "+targetClassName);
|
||||
}
|
||||
driver.get(targetClassHref);
|
||||
|
||||
driver.findElement(By.xpath("//a[@title='章节']")).click();
|
||||
@@ -423,13 +422,7 @@ public class CxstudyTask {
|
||||
public static CxstudyTask initialize(Config config) {
|
||||
log.info("任务创建中...");
|
||||
|
||||
WebDriverManager.firefoxdriver().clearDriverCache().setup();
|
||||
WebDriver driver = switch (config.getBrowser()) {
|
||||
case "firefox" -> config.isHeadless() ? new FirefoxDriver(new FirefoxOptions().addArguments("--headless")) : new FirefoxDriver();
|
||||
case "edge" ->config.isHeadless() ? new EdgeDriver(new EdgeOptions().addArguments("--headless")) : new EdgeDriver();
|
||||
case "chrome" ->config.isHeadless() ? new ChromeDriver(new ChromeOptions().addArguments("--headless")) : new ChromeDriver();
|
||||
default -> throw new IllegalStateException("不支持的浏览器驱动!: " + config.getBrowser());
|
||||
};
|
||||
WebDriver driver = TaskUtil.initDriver(config);
|
||||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
|
||||
Actions actions = new Actions(driver);
|
||||
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||
|
||||
236
src/main/java/work/slhaf/task/ZhsTask.java
Normal file
236
src/main/java/work/slhaf/task/ZhsTask.java
Normal file
@@ -0,0 +1,236 @@
|
||||
package work.slhaf.task;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openqa.selenium.*;
|
||||
import org.openqa.selenium.interactions.Actions;
|
||||
import org.openqa.selenium.support.ui.ExpectedConditions;
|
||||
import org.openqa.selenium.support.ui.WebDriverWait;
|
||||
import work.slhaf.config.Config;
|
||||
import work.slhaf.exception.TargetClassNotFoundException;
|
||||
import work.slhaf.exception.UnknownTaskPointException;
|
||||
import work.slhaf.util.TaskUtil;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Slf4j
|
||||
@Data
|
||||
public class ZhsTask {
|
||||
|
||||
private WebDriver driver;
|
||||
private Actions actions;
|
||||
private WebDriverWait wait;
|
||||
private JavascriptExecutor executor;
|
||||
private String targetClassName;
|
||||
private boolean aiEnable;
|
||||
|
||||
|
||||
public void run() throws InterruptedException {
|
||||
login();
|
||||
while (true) {
|
||||
try {
|
||||
switchPage();
|
||||
List<WebElement> todoTasks = getTodoTasks();
|
||||
while (!todoTasks.isEmpty()) {
|
||||
todoTasks.getFirst().click();
|
||||
System.out.println();
|
||||
try {
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='resources-list']")));
|
||||
} catch (Exception e) {
|
||||
driver.get(driver.getCurrentUrl());
|
||||
}
|
||||
HashMap<WebElement, String> todoTaskPoints = getTodoTaskPoints();
|
||||
log.info("发现{}个任务点", todoTaskPoints.size());
|
||||
AtomicInteger count = new AtomicInteger(0);
|
||||
for (Map.Entry<WebElement, String> entry : todoTaskPoints.entrySet()) {
|
||||
WebElement k = entry.getKey();
|
||||
String v = entry.getValue();
|
||||
count.incrementAndGet();
|
||||
log.info("处理第{}个任务点", count.get());
|
||||
switch (v) {
|
||||
case "icon-box video" -> handleVideoTask(k);
|
||||
case "icon-box baidu" -> handleWebTask(k);
|
||||
case "icon-box book", "icon-box other", "icon-box img" -> handleDocTask(k);
|
||||
default -> throw new UnknownTaskPointException("未设置处理策略的任务点类型!");
|
||||
}
|
||||
}
|
||||
driver.findElement(By.xpath("//img[@alt='back']")).click();
|
||||
todoTasks = getTodoTasks();
|
||||
}
|
||||
log.info("任务完成!");
|
||||
driver.quit();
|
||||
break;
|
||||
}catch (WebDriverException e) {
|
||||
log.error("\r\n---------------\r\n");
|
||||
log.error(e.getLocalizedMessage());
|
||||
log.error("\r\n---------------\r\n");
|
||||
log.error("Something went wrong, will retry later..");
|
||||
driver.get("https://onlineweb.zhihuishu.com/onlinestuh5");
|
||||
Thread.sleep(5000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleWebTask(WebElement task) throws InterruptedException {
|
||||
//记录当前句柄
|
||||
String primaryHandle = driver.getWindowHandle();
|
||||
task.click();
|
||||
Thread.sleep(1000);
|
||||
Set<String> handles = driver.getWindowHandles();
|
||||
handles.forEach(s -> {
|
||||
if (!s.equals(primaryHandle)) {
|
||||
driver.switchTo().window(s);
|
||||
driver.close();
|
||||
}
|
||||
});
|
||||
driver.switchTo().window(primaryHandle);
|
||||
}
|
||||
|
||||
private void handleDocTask(WebElement task) throws InterruptedException {
|
||||
task.click();
|
||||
Thread.sleep(2000);
|
||||
}
|
||||
|
||||
private void handleVideoTask(WebElement videoTask) throws InterruptedException {
|
||||
videoTask.click();
|
||||
log.info("处理视频播放任务...");
|
||||
Thread.sleep(2000);
|
||||
//模拟移动鼠标使元素显现
|
||||
actions.moveToElement(driver.findElement(By.xpath("//div[@class='video-progress']"))).perform();
|
||||
actions.moveByOffset(-10, -10).perform();
|
||||
|
||||
//开启倍速
|
||||
try {
|
||||
driver.findElement(By.xpath("//div[@class='speedTab speedTab15']")).click();
|
||||
}catch (Exception ignored) {}
|
||||
String currentTime = "00:00:00";
|
||||
String duration = "00:00:00";
|
||||
while (true) {
|
||||
Thread.sleep(1000);
|
||||
actions.moveToElement(driver.findElement(By.xpath("//div[@class='video-progress']"))).perform();
|
||||
actions.moveByOffset(-10, -10).perform();
|
||||
|
||||
try {
|
||||
currentTime = driver.findElement(By.xpath(".//span[@class='currentTime']")).getText();
|
||||
duration = driver.findElement(By.xpath(".//span[@class='duration']")).getText();
|
||||
}catch (Exception ignored) {}
|
||||
if (currentTime.equals("00:00:00")) {
|
||||
continue;
|
||||
}else {
|
||||
log.info("{}/{}", currentTime, duration);
|
||||
}
|
||||
if (currentTime.equals(duration)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
log.info("视频播放任务完成");
|
||||
|
||||
|
||||
}
|
||||
|
||||
private HashMap<WebElement, String> getTodoTaskPoints() {
|
||||
HashMap<WebElement, String> todoTaskPoints = new HashMap<>();
|
||||
WebElement taskPointList = driver.findElement(By.xpath("//div[@class='resources-list']"));
|
||||
List<WebElement> totalTaskPoints = taskPointList.findElements(By.xpath(".//div[@class='resources-item']"));
|
||||
for (WebElement taskPoint : totalTaskPoints) {
|
||||
try {
|
||||
//如果找到完成标签,则直接进行下次循环
|
||||
taskPoint.findElement(By.xpath(".//div[@class='finished-icon']"));
|
||||
continue;
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
//根据div标签属于icon-box video还是icon-box baidu来确定处理策略,先放在hashmap中
|
||||
String classAttribute = taskPoint.findElement(By.xpath(".//div[contains(@class, 'icon-box')]")).getDomAttribute("class");
|
||||
todoTaskPoints.put(taskPoint, classAttribute);
|
||||
}
|
||||
return todoTaskPoints;
|
||||
}
|
||||
|
||||
private List<WebElement> getTodoTasks() {
|
||||
List<WebElement> totalTasks;
|
||||
List<WebElement> todoTasks = new ArrayList<>();
|
||||
boolean pct = false;
|
||||
try {
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='item-content']")));
|
||||
totalTasks = driver.findElements(By.xpath("//div[@class='item-content']"));
|
||||
} catch (TimeoutException ignored) {
|
||||
try {
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@class='knowledge-point']")));
|
||||
} catch (TimeoutException e) {
|
||||
throw new TimeoutException();
|
||||
}
|
||||
pct = true;
|
||||
totalTasks = driver.findElements(By.xpath("//div[@class='knowledge-point']"));
|
||||
}
|
||||
for (WebElement task : totalTasks) {
|
||||
String progress;
|
||||
if (pct) {
|
||||
progress = task.findElement(By.xpath(".//div[@class='pct-text']")).getText();
|
||||
} else {
|
||||
progress = task.findElement(By.xpath(".//span[@class='progress-num']")).getText();
|
||||
}
|
||||
if (progress.equals("100%")) {
|
||||
continue;
|
||||
}
|
||||
todoTasks.add(task);
|
||||
}
|
||||
log.info("获取到{}个任务", todoTasks.size());
|
||||
return todoTasks;
|
||||
}
|
||||
|
||||
private void switchPage() {
|
||||
log.info("跳转中...");
|
||||
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@class='courseName']")));
|
||||
List<WebElement> classes = driver.findElements(By.xpath("//a[@class='courseName']"));
|
||||
boolean flag = false;
|
||||
WebElement targetClass = null;
|
||||
for (WebElement aClass : classes) {
|
||||
if (aClass.getText().equals(targetClassName)) {
|
||||
targetClass = aClass;
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
throw new TargetClassNotFoundException("未找到课程: " + targetClassName);
|
||||
}
|
||||
targetClass.click();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private void login() {
|
||||
log.info("登录中...");
|
||||
driver.get("https://onlineweb.zhihuishu.com/onlinestuh5");
|
||||
WebElement qqlogin = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@class='wall-icon wall-qq']")));
|
||||
qqlogin.click();
|
||||
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("ptlogin_iframe"));
|
||||
driver.findElement(By.xpath("//a[@class='face']")).click();
|
||||
log.info("登录成功!");
|
||||
}
|
||||
|
||||
public static ZhsTask initialize(Config config) {
|
||||
log.info("任务创建中...");
|
||||
WebDriver driver = TaskUtil.initDriver(config);
|
||||
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(8));
|
||||
Actions actions = new Actions(driver);
|
||||
JavascriptExecutor executor = (JavascriptExecutor) driver;
|
||||
|
||||
ZhsTask zhsTask = getZhsTask(config, driver, wait, actions, executor);
|
||||
return zhsTask;
|
||||
}
|
||||
|
||||
private static ZhsTask getZhsTask(Config config, WebDriver driver, WebDriverWait wait, Actions actions, JavascriptExecutor executor) {
|
||||
ZhsTask zhsTask = new ZhsTask();
|
||||
zhsTask.setDriver(driver);
|
||||
zhsTask.setWait(wait);
|
||||
zhsTask.setActions(actions);
|
||||
zhsTask.setExecutor(executor);
|
||||
|
||||
zhsTask.setTargetClassName(config.getZhsConfig().getTarget());
|
||||
|
||||
zhsTask.setAiEnable(config.isAiEnable());
|
||||
return zhsTask;
|
||||
}
|
||||
}
|
||||
33
src/main/java/work/slhaf/util/TaskUtil.java
Normal file
33
src/main/java/work/slhaf/util/TaskUtil.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package work.slhaf.util;
|
||||
|
||||
import io.github.bonigarcia.wdm.WebDriverManager;
|
||||
import org.openqa.selenium.WebDriver;
|
||||
import org.openqa.selenium.chrome.ChromeDriver;
|
||||
import org.openqa.selenium.chrome.ChromeOptions;
|
||||
import org.openqa.selenium.edge.EdgeDriver;
|
||||
import org.openqa.selenium.edge.EdgeOptions;
|
||||
import org.openqa.selenium.firefox.FirefoxDriver;
|
||||
import org.openqa.selenium.firefox.FirefoxOptions;
|
||||
import work.slhaf.config.Config;
|
||||
|
||||
public class TaskUtil {
|
||||
private TaskUtil() {}
|
||||
|
||||
public static WebDriver initDriver(Config config) {
|
||||
return switch (config.getBrowser()) {
|
||||
case "firefox" -> {
|
||||
WebDriverManager.firefoxdriver().clearDriverCache().setup();
|
||||
yield config.isHeadless() ? new FirefoxDriver(new FirefoxOptions().addArguments("--headless")) : new FirefoxDriver();
|
||||
}
|
||||
case "edge" -> {
|
||||
WebDriverManager.edgedriver().clearDriverCache().setup();
|
||||
yield config.isHeadless() ? new EdgeDriver(new EdgeOptions().addArguments("--headless")) : new EdgeDriver();
|
||||
}
|
||||
case "chrome" -> {
|
||||
WebDriverManager.chromedriver().clearDriverCache().setup();
|
||||
yield config.isHeadless() ? new ChromeDriver(new ChromeOptions().addArguments("--headless")) : new ChromeDriver();
|
||||
}
|
||||
default -> throw new IllegalStateException("不支持的浏览器驱动!: " + config.getBrowser());
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import java.io.IOException;
|
||||
|
||||
public class ProjectTest {
|
||||
|
||||
@Test
|
||||
// @Test
|
||||
public void configTest() throws IOException {
|
||||
Config config = Config.load();
|
||||
System.out.println(config.toString());
|
||||
|
||||
Reference in New Issue
Block a user