方案介绍
因为项目需要,一直在研究java的网页的全屏截图方案。网上开源的各种库和项目往往有以下问题:
- 网页兼容性不好。比如无法运行JavaScript,无法兼容CSS3等等问题。
- 没有持续维护。由于网页的技术迭代比较快,没人维护就意味着兼容性很差,稳定性也堪忧。
- 方案太复杂。能完美实现网页截图的库很少,能实现全屏截图的就更是稀少了。
后来,自己研究了很久,发现通过selenium来实现全屏截图,是所有方案中性价比最高的。
代码演示
首先,你要在你的环境中安装chrome+chromedriver。注意这两个软件的版本要搭配。
然后通过maven的pom来引入selenium包,代码如下:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.8.0</version>
</dependency>
成功引入selenium后,即可通过代码来打开网页,然后截图。代码如下:
package com.coderbbb.blogv2.utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverLogLevel;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class SeleniumUtil {
public static WebDriver webDriver;
public static ConcurrentHashMap<String, String> HTML_IMAGE_CACHE = new ConcurrentHashMap<>();
private static final Logger logger = LoggerFactory.getLogger(SeleniumUtil.class);
public synchronized static void init() {
if (webDriver == null) {
// System.setProperty("webdriver.chrome.driver", "D:\\software\\chrome-driver\\chromedriver.exe");
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setLogLevel(ChromeDriverLogLevel.WARNING);
// 设置后台静默模式启动浏览器
chromeOptions.setHeadless(true);
chromeOptions.setExperimentalOption("excludeSwitches", Collections.singletonList("enable-automation"));
Map<String, Object> prefs = new HashMap<>();
prefs.put("credentials_enable_service", false);
prefs.put("profile.password_manager_enabled", false);
chromeOptions.addArguments("--disable-blink-features");
chromeOptions.addArguments("--disable-blink-features=AutomationControlled");
chromeOptions.setExperimentalOption("prefs", prefs);
chromeOptions.addArguments("--no-sandbox");
chromeOptions.addArguments("--disable-dev-shm-usage");
chromeOptions.addArguments("--incognito");
chromeOptions.addArguments("--disable-gpu");
chromeOptions.addArguments("--ignore-certificate-errors");
chromeOptions.addArguments("--ignore-ssl-errors");
String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36";
userAgent = "user-agent=" + userAgent;
chromeOptions.addArguments(userAgent);
chromeOptions.addArguments("--start-maximized");
//不加载图片, 提升速度
// chromeOptions.addArguments("blink-settings=imagesEnabled=false");
webDriver = new ChromeDriver(chromeOptions);
//设置窗口大小
Dimension dimension = new Dimension(1920, 30);
webDriver.manage().window().setSize(dimension);
}
}
public static WebDriver getWebDriver() {
if (webDriver == null) {
init();
}
return webDriver;
}
public static void main(String[] args) throws Exception {
System.setProperty("webdriver.chrome.driver", "D:\\software\\chrome-driver\\chromedriver.exe");
getWebDriver().get("https://www.coderbbb.com");
//TODO:这里最好通过WebDriverWait来等待网页加载完毕。否则可能截图时,网页并没有加载完成。
//根据内容,重新设定窗口大小
JavascriptExecutor javascriptExecutor = (JavascriptExecutor) getWebDriver();
Long height = (Long) javascriptExecutor.executeScript("return document.documentElement.scrollHeight");
Dimension dimension = new Dimension(1920, height.intValue());
getWebDriver().manage().window().setSize(dimension);
WebDriverWait webDriverWait = new WebDriverWait(getWebDriver(), Duration.ofSeconds(20));
webDriverWait.until(new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver d) {
int heightNow = getWebDriver().manage().window().getSize().getHeight();
return heightNow == height.intValue();
}
});
File file = ((TakesScreenshot) getWebDriver()).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file, new File("./coderbbb.png"));
getWebDriver().close();
}
}
全屏截图的实现方法:通过selenium在chrome中运行JavaScript脚本,获取网页的高度。然后用该高度来重新设置chrome的窗口高度,从而使不管多长的网页都能一屏显示完毕,避免网页出现滚动条。
效果展示
运行上面代码中的main方法后,你就能在项目当前目录看到一张coderbbb.png的截图