当前位置: 首页 > news >正文

Java/Kotlin selenium 无头浏览器 [Headless Chrome] 实现长截图

一、CDP 截图

CDP 截图,是通过 Chrome 的 Chrome DevTools Protocol (CDP) 协议进行截图。如果需要使用这个,需要保证 浏览器版本,浏览器驱动,项目 selenium 依赖,chrome cdp 的依赖。这些版本需要对应后,才能正常使用。

// 1. 查找 CDP 版本
Optional<CdpVersion> optional = new CdpVersionFinder().match(driver.capabilities.browserVersion);
if (!optional.isPresent()) {throw new RuntimeException("No CDP version found. Please check the browser version to select the correct CDP version");
}// 2. 构造参数
Map<String, Object> params = new HashMap<>();
params.put("format", "png");
params.put("captureBeyondViewport", true);// 3. 执行 CDP 命令
@SuppressWarnings("unchecked")
Map<String, String> response = (Map<String, String>) driver.executeCdpCommand("Page.captureScreenshot", params);// 4. 提取并处理 base64 图像数据
String data = response.get("data");
String base64Image = data.replaceFirst("^data:image/png;base64,", "");

二、修改浏览器大小截图

通过将浏览器的大小修改为页面的大小,这样截图天生就是长截图但是需要注意:如果想要截图需要使用无头浏览器,否则截取的图片大小不会超过视窗窗口的大小的。


public class ScreenshotUtils {/*** 截取整个页面的屏幕截图(包括超出视口的部分)** @param instance   TakesScreenshot 实例(WebDriver 或 WebElement)* @param returnType 返回类型(如 OutputType.FILE 或 OutputType.BYTES)* @param <T>        返回值类型* @return 截图结果*/public static <T> T fullScreenshotAsT(TakesScreenshot instance, Class<T> returnType) {WebDriver driver;// 确定 WebDriver 实例if (instance instanceof WebDriver) {driver = (WebDriver) instance;} else if (instance instanceof WebElement) {if (instance instanceof WrapsDriver) {driver = ((WrapsDriver) instance).getWrappedDriver();} else {throw new UnsupportedOperationException("WebElement does not wrap a WebDriver");}} else {throw new UnsupportedOperationException("Unsupported TakesScreenshot type: " + instance.getClass().getName());}// 获取原始窗口大小Dimension originalSize = driver.manage().window().getSize();// 获取整个页面的滚动尺寸Dimension scrollSize = getFullPageSize(driver);// 调整窗口大小以适应整个页面driver.manage().window().setSize(scrollSize);T screenshot = null;try {// 截图screenshot = instance.getScreenshotAs(returnType);} finally {// 恢复窗口大小driver.manage().window().setSize(originalSize);}return screenshot;}/*** 获取整个页面的滚动尺寸(包括超出视口的部分)** @param driver WebDriver 实例* @return 页面的完整尺寸*/private static Dimension getFullPageSize(WebDriver driver) {JavascriptExecutor js = (JavascriptExecutor) driver;Long scrollHeight = (Long) js.executeScript("return Math.max(document.body.scrollHeight, document.documentElement.scrollHeight)");Long scrollWidth = (Long) js.executeScript("return Math.max(document.body.scrollWidth, document.documentElement.scrollWidth)");return new Dimension(scrollWidth.intValue(), scrollHeight.intValue());}
}

三、 AShot 截图库

public class ScreenshotUtils {/*** 获取当前页面的 devicePixelRatio(DPR)** @param driver WebDriver 实例* @return devicePixelRatio 值*/public static float getDevicePixelRatio(WebDriver driver) {Object result = ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio;");if (result instanceof Number) {return ((Number) result).floatValue();}return 1.0f; // 默认值}/*** 使用 AShot 截图策略,返回 BufferedImage** @param instance TakesScreenshot 实例(WebDriver 或 WebElement)* @param <T>      返回值类型(如 BufferedImage)* @return 截图的 BufferedImage*/public static BufferedImage takeScreenshotWithDpr(TakesScreenshot instance) {WebDriver driver;if (instance instanceof WebDriver) {driver = (WebDriver) instance;} else if (instance instanceof WebElement) {if (instance instanceof WrapsDriver) {driver = ((WrapsDriver) instance).getWrappedDriver();} else {throw new UnsupportedOperationException("WebElement does not wrap a WebDriver");}} else {throw new UnsupportedOperationException("Unsupported TakesScreenshot type: " + instance.getClass().getName());}float dpr = getDevicePixelRatio(driver);ShootingStrategy shootingStrategy = ShootingStrategies.viewportRetina(800, 0, 0, dpr);AShot aShot = new AShot().shootingStrategy(shootingStrategy).coordsProvider(new WebDriverCoordsProvider());BufferedImage bufferedImage;if (instance instanceof WebDriver) {bufferedImage = aShot.takeScreenshot(driver).getImage();} else if (instance instanceof WebElement) {WebElement element = (WebElement) instance;bufferedImage = aShot.takeScreenshot(driver, element).getImage();} else {throw new IllegalStateException("Unexpected TakesScreenshot instance");}return bufferedImage;}
}

相关文章:

  • 2025神经网络动力学理论、优化算法及应用专题研讨会 ( NOTAA 2025)
  • 一键生成活动页面的智能体开发实践:从策划到分发的全自动化解决方案
  • Android studio中git突然看不了提交记录
  • flink1.19.2+cdc-3.2.1遇到的问题及解决方案
  • 【AI大模型入门指南】概念与专有名词详解 (二)
  • 达梦数据库单机部署dmhs同步复制(dm8->kafka)
  • mac电脑.sh文件,用来清除git当前分支
  • 代码填空题技术实现:突破 highlight.js 安全限制的工程实践
  • 数值偏微分方程的代数骨架:线性代数及其挑战-AI云计算
  • Cilium动手实验室: 精通之旅---23.Advanced Gateway API Use Cases
  • 机器学习与深度学习18-线性代数01
  • 老飞飞bug及原理修复方法
  • android studio向左向右滑动页面
  • 【Zephyr 系列 19】打造 BLE 模块完整 SDK:AT 命令系统 + 状态机 + NVS + OTA 一体化构建
  • Kotlin基础语法五
  • 调试`build.sh` 和用 `CMake` 编译出来的 `.elf` / `.bin` / `.hex` 文件大小或行为不同?
  • 大模型在输尿管下段积水预测及临床应用的研究
  • uni-app学习笔记三十六--分段式选项卡组件的使用
  • 电机控制基础,小白入门篇
  • Windows笔记之Win11让非焦点窗口程序也能获得流畅性能的方法
  • 关于网站建设征求意见/职业教育培训机构排名前十
  • 2015做那些网站致富/免费搭建个人网站
  • 淄博学校网站建设哪家好/最近的新闻有哪些
  • 网站建设工作总结6/巢湖seo推广
  • 天津哪里有做网站的/ip域名查询网
  • 营业范围中网站开发与网页设计/广州品牌seo推广