- package sample;
-
- import javafx.application.Application;
- import javafx.concurrent.Task;
- import javafx.scene.Scene;
- import javafx.scene.control.*;
- import javafx.scene.control.Alert;
- import javafx.scene.layout.VBox;
- import javafx.stage.Stage;
- import javafx.application.Platform;
- import java.io.File;
- import java.net.HttpURLConnection;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.apache.commons.io.FileUtils;
- import org.openqa.selenium.*;
- import org.openqa.selenium.chrome.ChromeDriver;
- import org.openqa.selenium.chrome.ChromeOptions;
-
- import javax.swing.*;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.URL;
- import java.util.Random;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
- public class main extends Application {
- private TextField shareUrlField = new TextField();
- private CheckBox testOpenCheckbox = new CheckBox("调试");
- private TextField testPathField = new TextField();
- private TextField testTimeField = new TextField();
- private Button downloadButton = new Button("下载视频");
- private ProgressBar progressBar = new ProgressBar(0);
-
- // 默认等待时间
- private static final int DEFAULT_TEST_TIME = 5;
-
- private static final int WINDOW_WIDTH = 400;
- private static final int WINDOW_HEIGHT = 300;
-
-
- public static void main(String[] args) {
- launch(args);
- }
-
- @Override
- public void start(Stage primaryStage) {
- primaryStage.setTitle("视频下载器");
- primaryStage.setMinWidth(WINDOW_WIDTH);
- primaryStage.setMinHeight(WINDOW_HEIGHT);
- primaryStage.setMaxWidth(WINDOW_WIDTH);
- primaryStage.setMaxHeight(WINDOW_HEIGHT);
- progressBar.setPrefWidth(WINDOW_WIDTH);
-
- testTimeField.setPromptText("5"); // 设置默认值提示
- downloadButton.setOnAction(e -> {
- downloadButton.setDisable(true);
- downloadButton.setText("下载中...");
- String shareUrl = shareUrlField.getText();
- boolean testOpen = testOpenCheckbox.isSelected();
- String testPath = testPathField.getText();
- // 检查testTimeField是否为空,使用默认值
- int testTime = testTimeField.getText().isEmpty() ? DEFAULT_TEST_TIME : Integer.parseInt(testTimeField.getText());
- // 重置进度条
- progressBar.setProgress(0);
- // 创建一个后台任务
- Task<Void> downloadTask = new Task<Void>() {
- @Override
- protected Void call() throws Exception {
- // 在这里调用您的视频下载代码,将用户输入传递给下载方法
- downloadVideo(shareUrl, testOpen, testPath, testTime);
- return null;
- }
- };
-
- downloadTask.setOnSucceeded(event -> {
- // 下载完成时的处理,例如弹出消息或其他操作
- downloadButton.setText("下载视频");
- downloadButton.setDisable(false);
- });
-
- downloadTask.setOnFailed(event -> {
- // 下载失败时的处理
- downloadButton.setText("下载视频");
- downloadButton.setDisable(false);
- });
- // 启动任务
- Thread downloadThread = new Thread(downloadTask);
- downloadThread.setDaemon(true); // 设置为守护线程,以便在主窗口关闭时终止下载
- downloadThread.start();
-
- });
-
- VBox vbox = new VBox(10);
- vbox.setPrefWidth(WINDOW_WIDTH); // 设置首选宽度
- vbox.setPrefHeight(WINDOW_HEIGHT); // 设置首选高度
- vbox.getChildren().addAll(
- new Label("modal_id:"),
- shareUrlField,
-
- new Label("下载路径:(\\结尾)"),
- testPathField,
- new Label("等待时间 (秒):"),
- testTimeField,
- testOpenCheckbox,
- downloadButton,
- progressBar
- );
-
- Scene scene = new Scene(vbox, WINDOW_WIDTH, WINDOW_HEIGHT); // 设置Scene的宽度和高度
- primaryStage.setScene(scene);
- primaryStage.show();
- }
-
- private void downloadVideo(String Url, boolean testOpen, String testPath, int testTime) {
- // 在这里调用您的视频下载代码,将用户输入传递给下载方法
- System.setProperty("webdriver.chrome.driver", "C:\\chromedriver.exe");
- ChromeOptions chromeOptions = new ChromeOptions();
- chromeOptions.addArguments("--headless"); // 启用无头模式
- chromeOptions.addArguments("--disable-gpu"); // 禁用GPU加速
- chromeOptions.addArguments("--headless", "--no-sandbox"); //禁用沙盒模式
- WebDriver driver = new ChromeDriver(chromeOptions);
- // //URL
- String shareUrl="https://www.douyin.com/video/"+Url;
- // //测试地址
- // Boolean testOpen=true;
- // //下载路径
- // String testPath="C:\\Users\\T\\Desktop\\";
- // //等待时间
- // int testTime=5;
- try{
- driver.get(shareUrl); // 替换为目标页面的URL
- Thread.sleep(testTime*1000);
- String localPath=testPath;
- String absoluteFilePath = localPath+"screenshot.png"; // 使用绝对文件路径
- if(testOpen){
- File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
- FileUtils.copyFile(screenshot, new File(absoluteFilePath));
- }
- // 获取页面源代码
- String pageSource = driver.getPageSource();
- driver.quit();
- //打开页面抓取
- // 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]"));
- // 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)"));
- // String dynamicData = dynamicDataElement.getText();
- // System.out.println("Dynamic Data: " + dynamicData);
- //无头模式正则
- String regex="(?<=
- Pattern pattern = Pattern.compile(regex);
- Matcher matcher = pattern.matcher(pageSource);
- String extractedString=null;
- while (matcher.find()) {
- extractedString = matcher.group();
- }
- //采集标题
- // String titleRegex="(?<=Nu66P_ba\">)(.*?)(?=)";
- // Pattern titlePattern = Pattern.compile(titleRegex);
- // Matcher titleMatcher = titlePattern.matcher(pageSource);
- // String titleExtractedString=random();
- // while (titleMatcher.find()) {
- // titleExtractedString = titleMatcher.group();
- // }
- String titleExtractedString=shareUrl.split("video/")[1];
- System.out.println("ID:"+titleExtractedString);
- System.out.println("https:"+extractedString);
- if(extractedString==null){
- Platform.runLater(() ->showErrorAlert("失败","下载失败"));
- }
- //下载视频
- down("https:"+extractedString,localPath,titleExtractedString);
- }catch(Exception e){
- System.out.println(e.getMessage());
- driver.quit();
- }
- }
- public void down(String videoURL,String localPath,String title){
- String savePath = localPath+title+".mp4"; // 本地保存视频的文件路径
- System.out.println("down——URL: " + videoURL);
- try {
- URL url = new URL(videoURL);
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-
- // 添加自定义请求头,模拟浏览器请求
- 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");
- 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");
- connection.setRequestProperty("Host", "www.douyin.com");
-
- InputStream inputStream = new ProgressMonitorInputStream(null, "正在下载视频", connection.getInputStream());
- FileOutputStream fileOutputStream = new FileOutputStream(savePath);
-
- byte[] buffer = new byte[4096];
- int bytesRead;
- long totalBytesRead = 0;
- long totalBytes = url.openConnection().getContentLength(); // 获取总字节数
-
- while ((bytesRead = inputStream.read(buffer)) != -1) {
- fileOutputStream.write(buffer, 0, bytesRead);
- totalBytesRead += bytesRead;
-
- // 计算下载进度
- int progress = (int) ((totalBytesRead * 100) / totalBytes);
- Platform.runLater(() ->setProgress(progress));
- System.out.println("下载进度: " + progress + "%");
- }
-
- inputStream.close();
- fileOutputStream.close();
-
- System.out.println("视频下载完成。");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- public void setProgress(int progress){
- progressBar.setProgress((double)progress/100);
- };
- public String random(){
- int length = 18;
- StringBuilder randomString = new StringBuilder();
-
- Random random = new Random();
-
- for (int i = 0; i < length; i++) {
- int digit = random.nextInt(10); // 生成0到9之间的随机数字
- randomString.append(digit);
- }
-
- String random18DigitNumber = randomString.toString();
- return random18DigitNumber;
- }
- // 弹出错误提示框
- private void showErrorAlert(String title, String content) {
- Alert alert = new Alert(Alert.AlertType.ERROR);
- alert.setTitle(title);
- alert.setHeaderText(null);
- alert.setContentText(content);
- alert.showAndWait();
- }
- }
pom
- <dependencies>
- <dependency>
- <groupId>org.seleniumhq.selenium</groupId>
- <artifactId>selenium-java</artifactId>
- <version>3.141.59</version> <!-- 版本号可以根据需要进行更改 -->
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.11.0</version> <!-- 使用最新版本 -->
- </dependency>
- </dependencies>
- <build>
- <!--打包成jar包时的名字-->
- <finalName>test</finalName>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-assembly-plugin</artifactId>
- <version>3.3.0</version>
- <configuration>
- <descriptorRefs>
- <descriptorRef>jar-with-dependencies</descriptorRef>
- </descriptorRefs>
- <archive>
- <manifest>
- <mainClass>sample.main</mainClass>
- </manifest>
- </archive>
- </configuration>
- <executions>
- <execution>
- <phase>package</phase>
- <goals>
- <goal>single</goal>
- </goals>
- </execution>
- </executions>
- </plugin>
- </plugins>
- </build>