java+selenium(资源全备,打开已使用浏览器信息,保留用户信息)
一、介绍
我的代码可以实现以下效果:
保留用户信息,好处:可以在登录好一个账号后还保留原来的token验证信息
使用java+selenium实现爬取vue元素内容,获取里面的视频,图片信息等
我使用的jdk是17版本,你们如果用自己版本不行就使用我一样版本的jdk再试试
二、准备
1.坐标
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
2.下载Chrome及驱动
–下载地址
Chrome for Testing availability
–注意事项
在这个网址里面包含了,驱动以及浏览器下载
你选一个喜欢的版本下载就是了,注意下载两个东西
chrome,chromedriver,下载时注意电脑是32,还是64位
如果你的电脑包含了chrome,那你打开右上角三个点,选择帮助,选择关于浏览器,然后就能看到电脑浏览器的版本以及位数
你就下载对应的chromedriver就行了
–旧版本地址
版本在114及以下:http://chromedriver.storage.googleapis.com/index.html
三、代码
1.测试
下载后将驱动的存放地址放进来,运行后打开了浏览器,就代表成功了
package com.ruoyi.catai;
import org.openqa.selenium.chrome.ChromeDriver;
public class VueScraper {
public static void main(String[] args) {
// 设置ChromeDriver路径
System.setProperty("webdriver.chrome.driver", "E:\\Project\\b-dimension\\b-dimension\\b-dimension\\b-fictiontweet\\src\\main\\java\\com\\ruoyi\\catai\\chromedriver-win64\\chromedriver.exe");
//打开浏览器
ChromeDriver chromeDriver=new ChromeDriver();
//访问百度
chromeDriver.get("http://www.baidu.com");
}
}
2.方法
–8个方法
findElement(By.id())
findElement(By.name())
findElement(By.className())
findElement(By.tagName())
findElement(By.linkText())
findElement(By.partialLinkText())
findElement(By.xpath())
findElement(By.cssSelector())
–使用案例
这是一个模拟登录的使用案例,还提供怎么获取多个元素集合
[]这个是用于属性的等值匹配的
// 使用CSS选择器定位class为el-input__inner且type为text的元素
WebElement usernameInput = driver.findElement(By.cssSelector(".el-input__inner[type='text']"));
// 输入用户名
usernameInput.sendKeys("xxx"); // 定位用户名输入框,需要根据实际页面元素的 ID、name、class 等属性进行调整
// 定位密码输入框,同样需要根据实际页面元素进行调整
//WebElement passwordInput = driver.findElement(By.id("password"));
WebElement passwordInput = driver.findElement(By.cssSelector(".el-input__inner[type='password']"));
// 输入密码
passwordInput.sendKeys("xxx");
// 定位登录按钮,根据实际页面元素进行调整
WebElement loginButton = driver.findElement(By.cssSelector(".el-button[type='button']"));
// 点击登录按钮
loginButton.click();
// 等待登录完成,可以根据实际情况调整等待时间
Thread.sleep(10000);*/
//driver.get("https://aigcbus.com/home/drawing");
List<WebElement> mebox = driver.findElements(By.cssSelector(".message_box"));
System.out.println(mebox.size());
四、优化
1.保留用户信息
上面的代码每次都是打开新的浏览器,之前的使用记录也没有,非常麻烦
我就通过保存浏览器的信息到本地文件夹,每次打开就读取对应用户信息
package com.ruoyi.catai;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class VueScraper {
public static void main(String[] args) {
WebDriver driver = null;
try {
//杀死占用该端口的进程,避免之前打开后的残留进程影响程序
closeProcess("9222");
Thread.sleep(1000);
//运行浏览器在9222端口,指定保存和读取用户信息的文件夹
String fullCommand = "cmd /c \"C: && cd /d C:\\Program Files\\Google\\Chrome\\Application && chrome.exe --remote-debugging-port=9222 --user-data-dir=\"D:\\chrome_temp\"\"";
// 合并命令
Runtime.getRuntime().exec(fullCommand);
// 不等待 Chrome 进程结束,让 Java 程序继续执行
// int exitCode = process.waitFor();
// if (exitCode != 0) {
// throw new RuntimeException("命令执行失败,退出码: " + exitCode);
// }
System.out.println("Chrome 浏览器已启动");
// 设置 ChromeDriver 的路径
System.setProperty("webdriver.chrome.driver", "E:\\Project\\b-dimension\\b-dimension\\b-dimension\\b-fictiontweet\\src\\main\\java\\com\\ruoyi\\catai\\chromedriver-win64\\chromedriver.exe");
// 创建 ChromeOptions 对象,可用于设置浏览器选项
ChromeOptions options = new ChromeOptions();
//设置自动化工具打开的浏览器地址,为本机9222端口的浏览器
options.setExperimentalOption("debuggerAddress", "127.0.0.1:9222");
// 禁用一些不必要的浏览器功能,提高性能
options.addArguments(
"--disable-gpu",
"--no-sandbox"
);
// 创建 ChromeDriver 实例
driver = new ChromeDriver(options);
// 打开目标网页
driver.get("https://www.baidu.com");
// 等待页面加载完成,可以根据实际情况调整等待时间
Thread.sleep(5000);
/*// 使用CSS选择器定位class为el-input__inner且type为text的元素
WebElement usernameInput = driver.findElement(By.cssSelector(".el-input__inner[type='text']"));
// 输入用户名
usernameInput.sendKeys("xxx"); // 定位用户名输入框,需要根据实际页面元素的 ID、name、class 等属性进行调整
// 定位密码输入框,同样需要根据实际页面元素进行调整
//WebElement passwordInput = driver.findElement(By.id("password"));
WebElement passwordInput = driver.findElement(By.cssSelector(".el-input__inner[type='password']"));
// 输入密码
passwordInput.sendKeys("xxx");
// 定位登录按钮,根据实际页面元素进行调整
WebElement loginButton = driver.findElement(By.cssSelector(".el-button[type='button']"));
// 点击登录按钮
loginButton.click();
// 等待登录完成,可以根据实际情况调整等待时间
Thread.sleep(10000);*/
//driver.get("https://aigcbus.com/home/drawing");
List<WebElement> mebox = driver.findElements(By.cssSelector(".message_box"));
System.out.println(mebox.size());
// 使用findElements获取所有匹配的图片元素
List<WebElement> imgList = driver.findElements(By.cssSelector(".el-image__inner[style='object-fit: cover;']"));
//WebElement imgList = driver.findElement(By.cssSelector(".el-image__inner[style='object-fit: cover;']"));
imgList.forEach(img -> {
// 获取图片的src属性
String src = img.getAttribute("src");
System.out.println("图片地址:" + src);
});
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭浏览器
driver.quit();
}
}
/*public static void killProcessOnPort(int port) throws IOException, InterruptedException {
// 查找占用指定端口的进程 ID
String command = "netstat -ano | findstr :"+ port;
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
if (line.contains("LISTENING")) {
// 提取 PID
String[] parts = line.trim().split("\\s+");
String pid = parts[parts.length - 1];
// 杀死进程
String killCommand = "taskkill /F /PID " + pid;
Process killProcess = Runtime.getRuntime().exec(killCommand);
int exitCode = killProcess.waitFor();
if (exitCode == 0) {
System.out.println("成功杀死占用端口 " + port + " 的进程,PID: " + pid);
} else {
System.out.println("杀死占用端口 " + port + " 的进程失败,PID: " + pid);
}
}
}
reader.close();
}*/
public static void closeProcess(String port){
String command = "netstat -ano | findstr :" + port;
try {
// 执行命令
Process process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", command});
// 获取命令完成后输出
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
//匹配pid内容规则
Pattern pattern = Pattern.compile("\\s+(\\d+)$");
//接收PID集合
HashSet<String> set = new HashSet();
while ((line = reader.readLine()) != null) {
Matcher matcher = pattern.matcher(line);
if (matcher.find()) {
// 提取并打印PID
String pid = matcher.group(1);
set.add(pid);
}
}
//遍历关闭对应pid
set.forEach(s-> {
try {
System.out.println("pid:"+s);
Process process1 = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", "taskkill","/PID",s,"/F"});
} catch (IOException e) {
throw new RuntimeException(e);
}
});
// 等待进程结束
process.waitFor();
reader.close();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
2.总结
通过Java执行cmd命令打开谷歌浏览器,并指定保存用户信息的路径,也是读取用户信息的路径
自动化工具进入打开的这个谷歌浏览器,就能够实现,保留之前的登录信息了,无需再输入密码