• javaFx+google chrome测试下载视频


    1. package sample;
    2. import javafx.application.Application;
    3. import javafx.concurrent.Task;
    4. import javafx.scene.Scene;
    5. import javafx.scene.control.*;
    6. import javafx.scene.control.Alert;
    7. import javafx.scene.layout.VBox;
    8. import javafx.stage.Stage;
    9. import javafx.application.Platform;
    10. import java.io.File;
    11. import java.net.HttpURLConnection;
    12. import java.util.regex.Matcher;
    13. import java.util.regex.Pattern;
    14. import org.apache.commons.io.FileUtils;
    15. import org.openqa.selenium.*;
    16. import org.openqa.selenium.chrome.ChromeDriver;
    17. import org.openqa.selenium.chrome.ChromeOptions;
    18. import javax.swing.*;
    19. import java.io.File;
    20. import java.io.FileOutputStream;
    21. import java.io.IOException;
    22. import java.io.InputStream;
    23. import java.net.URL;
    24. import java.util.Random;
    25. import java.util.regex.Matcher;
    26. import java.util.regex.Pattern;
    27. public class main extends Application {
    28. private TextField shareUrlField = new TextField();
    29. private CheckBox testOpenCheckbox = new CheckBox("调试");
    30. private TextField testPathField = new TextField();
    31. private TextField testTimeField = new TextField();
    32. private Button downloadButton = new Button("下载视频");
    33. private ProgressBar progressBar = new ProgressBar(0);
    34. // 默认等待时间
    35. private static final int DEFAULT_TEST_TIME = 5;
    36. private static final int WINDOW_WIDTH = 400;
    37. private static final int WINDOW_HEIGHT = 300;
    38. public static void main(String[] args) {
    39. launch(args);
    40. }
    41. @Override
    42. public void start(Stage primaryStage) {
    43. primaryStage.setTitle("视频下载器");
    44. primaryStage.setMinWidth(WINDOW_WIDTH);
    45. primaryStage.setMinHeight(WINDOW_HEIGHT);
    46. primaryStage.setMaxWidth(WINDOW_WIDTH);
    47. primaryStage.setMaxHeight(WINDOW_HEIGHT);
    48. progressBar.setPrefWidth(WINDOW_WIDTH);
    49. testTimeField.setPromptText("5"); // 设置默认值提示
    50. downloadButton.setOnAction(e -> {
    51. downloadButton.setDisable(true);
    52. downloadButton.setText("下载中...");
    53. String shareUrl = shareUrlField.getText();
    54. boolean testOpen = testOpenCheckbox.isSelected();
    55. String testPath = testPathField.getText();
    56. // 检查testTimeField是否为空,使用默认值
    57. int testTime = testTimeField.getText().isEmpty() ? DEFAULT_TEST_TIME : Integer.parseInt(testTimeField.getText());
    58. // 重置进度条
    59. progressBar.setProgress(0);
    60. // 创建一个后台任务
    61. Task<Void> downloadTask = new Task<Void>() {
    62. @Override
    63. protected Void call() throws Exception {
    64. // 在这里调用您的视频下载代码,将用户输入传递给下载方法
    65. downloadVideo(shareUrl, testOpen, testPath, testTime);
    66. return null;
    67. }
    68. };
    69. downloadTask.setOnSucceeded(event -> {
    70. // 下载完成时的处理,例如弹出消息或其他操作
    71. downloadButton.setText("下载视频");
    72. downloadButton.setDisable(false);
    73. });
    74. downloadTask.setOnFailed(event -> {
    75. // 下载失败时的处理
    76. downloadButton.setText("下载视频");
    77. downloadButton.setDisable(false);
    78. });
    79. // 启动任务
    80. Thread downloadThread = new Thread(downloadTask);
    81. downloadThread.setDaemon(true); // 设置为守护线程,以便在主窗口关闭时终止下载
    82. downloadThread.start();
    83. });
    84. VBox vbox = new VBox(10);
    85. vbox.setPrefWidth(WINDOW_WIDTH); // 设置首选宽度
    86. vbox.setPrefHeight(WINDOW_HEIGHT); // 设置首选高度
    87. vbox.getChildren().addAll(
    88. new Label("modal_id:"),
    89. shareUrlField,
    90. new Label("下载路径:(\\结尾)"),
    91. testPathField,
    92. new Label("等待时间 (秒):"),
    93. testTimeField,
    94. testOpenCheckbox,
    95. downloadButton,
    96. progressBar
    97. );
    98. Scene scene = new Scene(vbox, WINDOW_WIDTH, WINDOW_HEIGHT); // 设置Scene的宽度和高度
    99. primaryStage.setScene(scene);
    100. primaryStage.show();
    101. }
    102. private void downloadVideo(String Url, boolean testOpen, String testPath, int testTime) {
    103. // 在这里调用您的视频下载代码,将用户输入传递给下载方法
    104. System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
    105. ChromeOptions chromeOptions = new ChromeOptions();
    106. chromeOptions.addArguments("--headless"); // 启用无头模式
    107. chromeOptions.addArguments("--disable-gpu"); // 禁用GPU加速
    108. chromeOptions.addArguments("--headless", "--no-sandbox"); //禁用沙盒模式
    109. WebDriver driver = new ChromeDriver(chromeOptions);
    110. // //URL
    111. String shareUrl="https://www.douyin.com/video/"+Url;
    112. // //测试地址
    113. // Boolean testOpen=true;
    114. // //下载路径
    115. // String testPath="C:\\Users\\T\\Desktop\\";
    116. // //等待时间
    117. // int testTime=5;
    118. try{
    119. driver.get(shareUrl); // 替换为目标页面的URL
    120. Thread.sleep(testTime*1000);
    121. String localPath=testPath;
    122. String absoluteFilePath = localPath+"screenshot.png"; // 使用绝对文件路径
    123. if(testOpen){
    124. File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    125. FileUtils.copyFile(screenshot, new File(absoluteFilePath));
    126. }
    127. // 获取页面源代码
    128. String pageSource = driver.getPageSource();
    129. driver.quit();
    130. //打开页面抓取
    131. // WebElement dynamicDataElement = driver.findElement(By.xpath("//*[@id=\"__next\"]/div[1]/div[3]/div/div/div[1]/div[1]/div[2]/div[1]/div[1]/div[1]/div[1]"));
    132. // WebElement dynamicDataElement =driver.findElement(By.cssSelector("#__next > div:nth-child(1) > div:nth-child(3) > div > div > div:nth-child(1) > div:nth-child(1) > div:nth-child(2) > div:nth-child(1) > div:nth-child(1) > div:nth-child(1)"));
    133. // String dynamicData = dynamicDataElement.getText();
    134. // System.out.println("Dynamic Data: " + dynamicData);
    135. //无头模式正则
    136. String regex="(?<=\" src=\")(.*?)(?=\")";
    137. Pattern pattern = Pattern.compile(regex);
    138. Matcher matcher = pattern.matcher(pageSource);
    139. String extractedString=null;
    140. while (matcher.find()) {
    141. extractedString = matcher.group();
    142. }
    143. //采集标题
    144. // String titleRegex="(?<=Nu66P_ba\">)(.*?)(?=)";
    145. // Pattern titlePattern = Pattern.compile(titleRegex);
    146. // Matcher titleMatcher = titlePattern.matcher(pageSource);
    147. // String titleExtractedString=random();
    148. // while (titleMatcher.find()) {
    149. // titleExtractedString = titleMatcher.group();
    150. // }
    151. String titleExtractedString=shareUrl.split("video/")[1];
    152. System.out.println("ID:"+titleExtractedString);
    153. System.out.println("https:"+extractedString);
    154. if(extractedString==null){
    155. Platform.runLater(() ->showErrorAlert("失败","下载失败"));
    156. }
    157. //下载视频
    158. down("https:"+extractedString,localPath,titleExtractedString);
    159. }catch(Exception e){
    160. System.out.println(e.getMessage());
    161. driver.quit();
    162. }
    163. }
    164. public void down(String videoURL,String localPath,String title){
    165. String savePath = localPath+title+".mp4"; // 本地保存视频的文件路径
    166. System.out.println("down——URL: " + videoURL);
    167. try {
    168. URL url = new URL(videoURL);
    169. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    170. // 添加自定义请求头,模拟浏览器请求
    171. connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36");
    172. connection.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7");
    173. connection.setRequestProperty("Host", "www.douyin.com");
    174. InputStream inputStream = new ProgressMonitorInputStream(null, "正在下载视频", connection.getInputStream());
    175. FileOutputStream fileOutputStream = new FileOutputStream(savePath);
    176. byte[] buffer = new byte[4096];
    177. int bytesRead;
    178. long totalBytesRead = 0;
    179. long totalBytes = url.openConnection().getContentLength(); // 获取总字节数
    180. while ((bytesRead = inputStream.read(buffer)) != -1) {
    181. fileOutputStream.write(buffer, 0, bytesRead);
    182. totalBytesRead += bytesRead;
    183. // 计算下载进度
    184. int progress = (int) ((totalBytesRead * 100) / totalBytes);
    185. Platform.runLater(() ->setProgress(progress));
    186. System.out.println("下载进度: " + progress + "%");
    187. }
    188. inputStream.close();
    189. fileOutputStream.close();
    190. System.out.println("视频下载完成。");
    191. } catch (IOException e) {
    192. e.printStackTrace();
    193. }
    194. }
    195. public void setProgress(int progress){
    196. progressBar.setProgress((double)progress/100);
    197. };
    198. public String random(){
    199. int length = 18;
    200. StringBuilder randomString = new StringBuilder();
    201. Random random = new Random();
    202. for (int i = 0; i < length; i++) {
    203. int digit = random.nextInt(10); // 生成09之间的随机数字
    204. randomString.append(digit);
    205. }
    206. String random18DigitNumber = randomString.toString();
    207. return random18DigitNumber;
    208. }
    209. // 弹出错误提示框
    210. private void showErrorAlert(String title, String content) {
    211. Alert alert = new Alert(Alert.AlertType.ERROR);
    212. alert.setTitle(title);
    213. alert.setHeaderText(null);
    214. alert.setContentText(content);
    215. alert.showAndWait();
    216. }
    217. }

    pom

    1. <dependencies>
    2. <dependency>
    3. <groupId>org.seleniumhq.selenium</groupId>
    4. <artifactId>selenium-java</artifactId>
    5. <version>3.141.59</version> <!-- 版本号可以根据需要进行更改 -->
    6. </dependency>
    7. <dependency>
    8. <groupId>commons-io</groupId>
    9. <artifactId>commons-io</artifactId>
    10. <version>2.11.0</version> <!-- 使用最新版本 -->
    11. </dependency>
    12. </dependencies>
    13. <build>
    14. <!--打包成jar包时的名字-->
    15. <finalName>test</finalName>
    16. <plugins>
    17. <plugin>
    18. <groupId>org.apache.maven.plugins</groupId>
    19. <artifactId>maven-assembly-plugin</artifactId>
    20. <version>3.3.0</version>
    21. <configuration>
    22. <descriptorRefs>
    23. <descriptorRef>jar-with-dependencies</descriptorRef>
    24. </descriptorRefs>
    25. <archive>
    26. <manifest>
    27. <mainClass>sample.main</mainClass>
    28. </manifest>
    29. </archive>
    30. </configuration>
    31. <executions>
    32. <execution>
    33. <phase>package</phase>
    34. <goals>
    35. <goal>single</goal>
    36. </goals>
    37. </execution>
    38. </executions>
    39. </plugin>
    40. </plugins>
    41. </build>

    编译好编译好的文件  需要下载谷歌浏览器 和对应的驱动文件,驱动文件放在C盘根目录下

  • 相关阅读:
    ThinkPHP 配置跨域请求,使用TP的内置跨域类配置,小程序和web网页跨域请求的区别及格式说明
    Spring是如何解决循环依赖问题的及三级缓存的作用
    【网页设计】期末大作业:化妆品主题——绿色大气的html5响应式化妆品护肤品肌肤网页设计(11页)
    STM32CubeMX SDRAM的使用(二)
    正向代理与反向代理
    下一代智能合约编程语言Move(四)
    “终于懂了” 系列:组件化框架 ARouter 完全解析(二)APT技术
    11. RBAC权限管理从零到一实现(二)
    [管理与领导-111]:IT人看清职场中的隐性规则 - 8 - 顺势而为在职场中的应用
    一次Kafka内存泄露排查经过
  • 原文地址:https://blog.csdn.net/zhang804633234/article/details/134202023