Java+Selenium如何实现将HTML页面转换成图片?
- 对于页面总高度比较小的页面,可以直接给Dimension设置一个比较大的高度,一次性截取;但是对于页面总高度比较大的页面,即使给Dimension设置一个非常大的高度,也无法截取完整的页面.
- 因为上述原因,我使用window.scrollBy(0,X)来滑动页面,想每次截高度X的内容,然后向下移动X,然后重新截图.但从结果来看,并不符合预期.截取的图片存在部分内容缺失.
我创建了一个最简单的页面,从下图可以看出,234~240丢失了,我想可能是scrollBy的原因,但是我不知道该怎么解决这个问题.
<!DOCTYPE html>
<html lang="en">
<body>
1<br>
2<br>
3<br>
4<br>
5<br>
.....
800<br>
</body>
</html>
public class HtmlToImage_Selenium {
public static void main(String[] args) {
// 路径
String chromePath = "D:\\htmlToImg\\Selenium\\chromedriver-win64\\chromedriver.exe";
String mergePath = "D:\\htmlToImg\\Selenium\\output\\merge.png";
String tempPath = "D:\\htmlToImg\\Selenium\\output\\screenshot_";
// 设置 ChromeDriver 路径
System.setProperty("webdriver.chrome.driver", chromePath);
// 设置 Chrome 选项
ChromeOptions options = new ChromeOptions();
// 无头模式
options.addArguments("--headless");
// 窗口大小
options.addArguments("--window-size=2160,1440");
// 创建 ChromeDriver
WebDriver driver = new ChromeDriver(options);
try {
// 加载 HTML 文件
driver.get("file:///D:/htmlToImg/Test.html");
// 使用显式等待,确保页面加载完成
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.tagName("body")));
// 获取页面总高度
JavascriptExecutor js = (JavascriptExecutor) driver;
long pageHeight = (long) js.executeScript("return document.body.scrollHeight;");
System.out.println("页面高度为" + pageHeight);
// 每次截取的高度
int captureHeight = 5000;
int numberOfScreenshots = (int) Math.ceil((double) pageHeight / captureHeight);
// 截取的图片的总高度
int totalHeight = 0;
List<File> files = new ArrayList<>();
for (int i = 0; i < numberOfScreenshots; i++) {
// 设置窗口大小
Dimension dimension = new Dimension(2160, captureHeight);
driver.manage().window().setSize(dimension);
// 截取屏幕并保存为临时图片
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
files.add(screenshot);
BufferedImage img = ImageIO.read(screenshot);
// 计算合并后的图片的总高度
totalHeight += img.getHeight();
System.out.println("第" + (i + 1) + "张图完成");
FileHandler.copy(screenshot, new File(tempPath + (i + 1) + ".png"));
// 使用JS滚动页面
js.executeScript("window.scrollBy(0, " + captureHeight + ");");
// 等待
Thread.sleep(500);
}
System.out.println(totalHeight);
int width = 0;
for (File file : files) {
BufferedImage img = ImageIO.read(file);
width = Math.max(img.getWidth(), width);
}
BufferedImage combinedImage = new BufferedImage(width, totalHeight,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = combinedImage.createGraphics();
int nowYIndex = 0;
for (File file : files) {
BufferedImage img = ImageIO.read(file);
g.drawImage(img, 0, nowYIndex, null);
nowYIndex += img.getHeight();
}
// 释放图形上下文
g.dispose();
// 保存合并后的大图
ImageIO.write(combinedImage, "PNG", new File(mergePath));
System.out.println("合并成功");
} catch (IOException | InterruptedException e) {
e.printStackTrace();
} finally {
// 关闭 WebDriver
driver.quit();
}
}
}
版本限定:JDK8+selenium-java(3.141.59)
我希望能通过JDK8+selenium生成给定的HTML静态页面的截图
看你思路是想多次截图拼接为一个完整图片。你可以每次滑动少一点,比如第二次截取的图片中有四分之一和上一张图片重合,存在重合部分就可以用算法把多张图片拼接成一张长图了。