java 实现网址的截图
maven 引入
<!--自动化测试工具,需要去其他网址下第三方包-->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<exclusions>
<exclusion>
<artifactId>guava</artifactId>
<groupId>com.google.guava</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
下载相关浏览器chrome
(windows)https://www.chromedownloads.net/chrome64win/
windows会自己更新,需要自己去禁止更新,不然测着测着,浏览器升级了(除非你旧版本打开以后,就不要关闭),导致代码报错
(linux)https://www.chromedownloads.net/chrome64linux/
linux系统不会自动更新的,不要担心
下载相关浏览器chromedriver驱动
我这边下载的也是98.0.4758.102版本
https://registry.npmmirror.com/binary.html?path=chromedriver/98.0.4758.102/

测试代码
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.epoint.third.apache.commons.io.FileUtils;
import com.linewell.gov.hoox.utils.log.LogUtil;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.File;
import java.io.IOException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/**
* 条件:需要谷歌浏览器版本和驱动版本一张
*/
public class SeleniumTools {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
Timestamp now1 = new Timestamp(startTime);
System.out.println("now1:" + now1);
for (int i = 0; i < 3; i++) {
try {
guge("D:/guge/img"+"/"+System.currentTimeMillis()+".png",
"https://mpage.taobao.com/hd/download.html",
"123");
} catch (Exception e) {
e.printStackTrace();
}
}
long between = DateUtil.between(new Date(startTime), new Date(), DateUnit.SECOND);
System.out.println("相差秒"+between);
System.out.println("相差分钟"+between/60);
}
//解决如下: 模拟浏览器滚动滚动条 解决懒加载问题
public static void guge(String hzdtpwzPath, String url, String nhhzdtoken) throws IOException {
LogUtil.info("=====guge=========");
LogUtil.info(hzdtpwzPath);
LogUtil.info(url);
LogUtil.info(nhhzdtoken);
// 根据系统来添加不同的驱动路径
String os = System.getProperty("os.name");
LogUtil.info(os);
String driverPath ="";
if (StrUtil.containsIgnoreCase(os, "Windows")) {//微软系统
driverPath+="D:\\chromedriver_win32 (98.0.4758.102)\\chromedriver.exe";
//程序执行,核心代码
processCMD("taskkill /F /im chromedriver.exe",1);
} else {//linux系统
driverPath+="/usr/local/xxxx/ChromeDriver/chromedriver_linux64/chromedriver";
//程序执行,核心代码
processCMD("ps -ef | grep Chrome | grep -v grep | awk '{print \"kill -9 \"$2}' | sh",2);
}
//频繁的启动关闭,会增加一个比较明显的延时导致浏览器进程不被关闭的情况发生,
// 为了避免这一状况我们可以通过ChromeDriverService来控制ChromeDriver进程的生死,
// 达到用完就关闭的效果避免进程占用情况出现(Running the server in a child process)
ChromeDriverService service =new ChromeDriverService.Builder().usingDriverExecutable(new File(driverPath)).usingAnyFreePort().build(); // 新建service 方便后面关闭chromedriver
service.start(); // 开启服务
ChromeOptions options = new ChromeOptions();
//ssl证书支持
options.setCapability("acceptSslCerts", true);
//截屏支持
options.setCapability("takesScreenshot", true);
//css搜索支持
options.setCapability("cssSelectorsEnabled", true);
//设置浏览器参数
// 设置无轨 开发时还是不要加,可以看到浏览器效果
options.addArguments("--headless");
options.addArguments("--no-sandbox");
options.addArguments("--disable-gpu");
options.addArguments("--disable-dev-shm-usage");
//处理僵尸进程
options.addArguments("--no-zygote");
//设置无头模式,一定要设置headless,否则只能截出电脑屏幕大小的图!!!
options.setHeadless(true);
WebDriver driver = new ChromeDriver(service,options);
//设置超时,避免有些内容加载过慢导致截不到图
driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.MINUTES);
driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
driver.manage().timeouts().setScriptTimeout(1, TimeUnit.MINUTES);
try {
//设置需要访问的地址
driver.get(url);
//先登录,再设置cookies
Cookie c1 = new Cookie("token", nhhzdtoken);
driver.manage().addCookie(c1);
//设置需要访问的地址
driver.get(url);
//获取高度和宽度一定要在设置URL之后,不然会导致获取不到页面真实的宽高;
Long width = (Long) ((ChromeDriver) driver).executeScript("return document.documentElement.scrollWidth");
Long height = (Long) ((ChromeDriver) driver).executeScript("return document.documentElement.scrollHeight");
LogUtil.info("宽带:" + width);
LogUtil.info("高度:" + height);
//这里需要模拟滑动,有些是滑动的时候才加在的
long temp_height = 0;
while (true) {
//每次滚动500个像素,因为懒加载所以每次等待2S 具体时间可以根据具体业务场景去设置
Thread.sleep(1000);
((ChromeDriver) driver).executeScript("window.scrollBy(0,500)");
temp_height += 500;
if (temp_height >= height) {
break;
}
}
//设置窗口宽高,设置后才能截全
driver.manage().window().setSize(new Dimension(width.intValue()+1120, height.intValue()+303));
//设置截图文件保存的路径
String screenshotPath = hzdtpwzPath;
File srcFile = ((ChromeDriver) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile, new File(screenshotPath));
LogUtil.info("设置浏览器截图文件保存的路径:" + screenshotPath);
} catch (Exception e) {
throw new RuntimeException("截图失败", e);
} finally {
//close仅仅关闭了当前页面,并未关闭chrome。
//使用quit则会真正退出chrome,结束进程。
//两者一起使用,才能避免频繁的启动关闭出现的卡住现象(重点)
driver.close();
driver.quit();
service.stop();
}
}
//直接杀进程
public static int processCMD(String commend,int type) {
//正常写 linux命令即可 、比如:mkdir xx/touch b.txt/sh start.sh/sh stop.sh
int i = 0;
Process process =null;
//程序执行,核心代码
try {
if(type==1){
//cmd /c dir 是执行完dir命令后关闭命令窗口。看需调整
String[] cmd = new String[]{"cmd","/c",commend};
process = Runtime.getRuntime().exec(cmd);
//也可以直接使用 process = Runtime.getRuntime().exec(commend)
}else{
//要想保证linux环境下命令能够执行成功,必须使用String[]
String[] cmd = new String[]{"sh","-c",commend};
process = Runtime.getRuntime().exec(cmd);
}
i = process.waitFor();
System.out.println("执行kill进程命令结果:" + i);
} catch (Exception e) {
e.printStackTrace();
}
return i;
}
//通常,安全编码规范中都会指出:使用Process.waitFor()的时候,
//可能导致进程阻塞,甚至死锁。
//使用java代码执行shell脚本,执行后会发现Java进程和Shell进程都会挂起,无法结束。
public static int processCMD2(String commend) {
//正常写 linux命令即可 、比如:mkdir xx/touch b.txt/sh start.sh/sh stop.sh
int i = 0;
Process process = null;
try {
process = Runtime.getRuntime().exec(commend);
//获取进程的标准输入流
final InputStream is1 = process.getInputStream();
//获取进城的错误流
final InputStream is2 = process.getErrorStream();
//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
new Thread(() -> {
BufferedReader br1 = new BufferedReader(new InputStreamReader(is1));
try {
String line1 = null;
while ((line1 = br1.readLine()) != null) {
if (line1 != null) {
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
BufferedReader br2 = new BufferedReader(new InputStreamReader(is2));
try {
String line2 = null;
while ((line2 = br2.readLine()) != null) {
if (line2 != null) {
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
//可能导致进程阻塞,甚至死锁
i = process.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
try {
process.getErrorStream().close();
process.getInputStream().close();
process.getOutputStream().close();
} catch (Exception ee) {
}
}
LogUtil.info("CMD2-执行kill进程命令:" + commend);
System.out.println("CMD2-执行kill进程命令:" + commend);
LogUtil.info("CMD2-执行kill进程命令结果:" + i);
System.out.println("CMD2-执行kill进程命令结果:" + i);
return i;
}
}
转自 https://blog.csdn.net/qq_20236937/article/details/132231095

浙公网安备 33010602011771号