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

JAVA服务端实现页面截屏(附代码)

JAVA服务端实现页面截屏

    • 适配需求
    • 方案一、使用JxBrowser
      • 使用步骤:
    • 方案二、JavaFX WebView
      • 使用步骤:
    • 方案三、Headless Chrome
      • 使用步骤:
    • 综上方案对比
    • 记录我的一个失败方案
    • 参考

适配需求

  1. 有正确完整的地址url;
  2. 通过浏览器能打开该url对应页面;
  3. 需要后台可以自动‘截屏’该页面;
  4. ‘截屏’后的页面可以输出文件(如pdf、png)格式;

方案一、使用JxBrowser

简介 :JxBrowser 具有多进程架构。 它在独立的本地进程中运行 Chromium,这些进程通过进程间通信 (IPC) 通道以光速与 Java 进行通信。 如果 Chromium 中出现错误,您的 Java 进程将保持活动状态。 这一切都与良好的用户体验和用户数据安全有关。​

架构逻辑如下
在这里插入图片描述

使用步骤:

  1. 先申请获得30天免费使用秘钥,也可以直接付费地址
  2. 获取 支持的Jar 包:
  3. Coding :
import static com.teamdev.jxbrowser.engine.RenderingMode.OFF_SCREEN;
import static com.teamdev.jxbrowser.print.PaperSize.ISO_A4;import com.teamdev.jxbrowser.browser.Browser;
import com.teamdev.jxbrowser.browser.callback.PrintCallback;
import com.teamdev.jxbrowser.browser.callback.PrintHtmlCallback;
import com.teamdev.jxbrowser.browser.callback.SaveAsPdfCallback;
import com.teamdev.jxbrowser.browser.event.PrintPreviewOpened;
import com.teamdev.jxbrowser.engine.Engine;
import com.teamdev.jxbrowser.engine.EngineOptions;
import com.teamdev.jxbrowser.engine.RenderingMode;
import com.teamdev.jxbrowser.frame.Frame;
import com.teamdev.jxbrowser.print.PdfPrinter;
import com.teamdev.jxbrowser.print.PrintJob;
import com.teamdev.jxbrowser.print.event.PrintCompleted;
import java.nio.file.Path;
import java.nio.file.Paths;public class JxBrowserDemo {// 构造一个浏览器实例public JxBrowserDemo() {// 设置证书秘钥System.setProperty("jxbrowser.license.key", "此处略");}// 执行方法public void run(String url) {EngineOptions engineOptions = EngineOptions.newBuilder(OFF_SCREEN).build();// 初始化 Chromium 引擎Engine engine = Engine.newInstance(engineOptions);// 创建一个浏览器实例Browser browser = engine.newBrowser();// 等待加载url完成browser.navigation().loadUrlAndWait(url);// 打印网络页面browser.mainFrame().ifPresent(frame -> System.out.println(frame.html()));browser.set(PrintCallback.class, (params, tell) -> {tell.print();});// 设置pdf文件导出位置browser.set(PrintHtmlCallback.class, (params, tell) -> {Path path = Paths.get("/Users/*****/temp3.pdf");PdfPrinter<PdfPrinter.HtmlSettings> printer = params.printers().pdfPrinter();PrintJob<PdfPrinter.HtmlSettings> printJob = printer.printJob();printJob.settings().paperSize(ISO_A4).enablePrintingBackgrounds().pdfFilePath(path).apply();printJob.on(PrintCompleted.class, event -> {if (event.isSuccess()) {System.out.println("Printing is completed successfully.");} else {System.out.println("Printing has failed.");}});tell.proceed(printer);});browser.mainFrame().ifPresent(frame -> {frame.print();});try {Thread.sleep(100000);}catch (InterruptedException e) {// do nothing}// 关闭引擎释放资源engine.close();}
}

方案二、JavaFX WebView

JavaFX WebView 是在 2014 年成为 JDK 8 的一部分的 JavaFX 2.0 中引入的。
如果您使用 Java 8,那么您不需要做任何特别的事情来开始使用 JavaFX WebView。
使用JDK 11及更高版本的JavaFX不再捆绑,因此要使用JavaFX 11或更高版本进行开发,您必须单独下载。

JavaFX在您的Java进程中初始化并运行WebKit。JavaFX允许您非常快速地创建和显示WebView。
然而WebKit会分配和使用Java进程的内存和CPU,一些现代网页可能会分配超过1GB的RAM。
您创建和加载网页的WebView实例越多,Java应用程序的RAM就越多(耗内存)。
在这里插入图片描述

使用步骤:

不需要额外操作直接coding即可
Coding :

import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;// 需要继承 javafx.application.Application
public class JavaFxDemo extends Application {private Scene scene;@Overridepublic void start(Stage stage) throws Exception {// 创建画布stage.setTitle("Web View");// 设置场景scene = new Scene(new Browser(), 750, 500, Color.web("#666970"));stage.setScene(scene);// 风格样式scene.getStylesheets().add("webviewsample/BrowserToolbar.css");stage.show();}
}
// 需要继承 Region
class Browser extends Region {final WebView browser = new WebView();// 浏览器引擎final WebEngine webEngine = browser.getEngine();public Browser() {// 浏览器应用风格getStyleClass().add("browser");// 加载web页面webEngine.load("http://www.oracle.com/products/index.html");// 页面增加到引擎中getChildren().add(browser);}private Node createSpacer() {Region spacer = new Region();HBox.setHgrow(spacer, Priority.ALWAYS);return spacer;}@Override protected void layoutChildren() {double w = getWidth();double h = getHeight();layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);}@Override protected double computePrefWidth(double height) {return 750;}@Override protected double computePrefHeight(double width) {return 500;}
}public class Application {public static void main(String[] args) {System.out.println("hello, world");javaFxDemo.run("https://www.baidu.com");}
}

方案三、Headless Chrome

简介:Headless Chrome 是 Chrome 浏览器的无界面形态,可以在不打开浏览器的前提下,使用所有 Chrome 支持的特性运行你的程序。

原理: 通过chromedriver 驱动加载对应页面,可以后台获取截图,并按照文件、字节流等方式返回;

使用步骤:

  1. 下载 chromedriver 和 同版本 的 chrome 到本地 驱动地址;
  2. 放置到系统对应位置(win系统在Windows目录下,Mac在包含bin的目录下),设置好执行权限;
  3. 引入 selenium-server-standalone.jar 依赖
<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.6.0</version>
</dependency>
  1. Coding :
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;@Service
public class ScreenshotService {private static WebDriver driver;@PostConstructprivate void initDriver(){ChromeOptions options = new ChromeOptions();/** 这里是设置要执行的命令* --headless: 不提供可视化页面(无头模式)* --disable-gpu: 禁用GPU加速* --window-size: 修改截图页面的尺寸 "--window-size=1920,1200"* --ignore-certificate-errors:*/options.addArguments("--headless", "--disable-gpu", "--window-size=1920,1920", "--ignore-certificate-errors");options.addArguments("--disable-dev-shm-usage", "--no-sandbox");driver = new ChromeDriver(options);}/*** 根据网络url获取网络截屏的字节数组* @param url 网络url* @return 字节数组*/private static synchronized byte[] getFileByteArry(String url){// 1.打印chromedriver驱动log.info("[页面抓取]- {}", driver);long startTime = System.currentTimeMillis();// 2.加载web页面driver.get(url);// 3.页面等待渲染时长,如果你的页面需要动态渲染数据的话一定要留出页面渲染的时间,单位默认是秒new WebDriverWait(driver, 5);// 4.获取到截图的文件字节byte[] byteArry = ((TakesScreenshot) driver).getScreenshotAs(OutputType.BYTES);log.info("[页面抓取]ChromeDriver处理结束用时{}s, Title:{}", calUsedTime(startTime), driver.getTitle());return byteArry;}
}

【开发过程中我实际遇到的问题】:
1.代码指定浏览器驱动位置无效, 生成驱动时按照系统自动加载:win系统在Windows目录下,Mac在包含bin的目录下;
2.Mac系统中驱动需要权限,Win不需要可权限可直接执行;
3.页面大小设置问题:不提供可视化页面情况下必须指定截图页面尺寸,自上而下自左而右截取(可能有丢失内容风险);
4.如果设置页面渲染超时间(可以去除该设置):默认需要指定加载到页面Element标签ID,如果页面不含该ID则报错;


综上方案对比

JxBrowserJavaFXHeadless
开源否,需付费
依赖第三方包JDKselenium +谷歌驱动
操作复杂,需要申请令牌和增加依赖简单复杂,下载安装驱动和浏览器并增加依赖
代码复杂度简单,依赖包强大稍复杂,需要有抽象和分层概念简单,面向对象概念
耗时快 2-3秒一般 3-5秒慢 4-6秒
页面效果nice一般nice
不足依赖第三方服务无法后台存储,需要弹窗选择执行稍慢

记录我的一个失败方案

思路:通过get请求url获得一个html响应,将html打印获取页面;
失败原因:html需要在线获取一些前端样式(js、css)渲染,如果直接打印可能只是一个空页面。必须要经过web端进行渲染才能实现基本的页面格式。


参考

文章为个人实际开发完成后的技术整理
有相关问题可以参考我当时查资料的参考(帮您节省时间),如下:

JxBrowser
知乎 · 什么是 JxBrowser
JavaFX入门介绍
知乎 · JxBrowser还是JavaFX WebView
CSDN · Headless Chrome
CSDN · 使用ChromeHeadLess

相关文章:

JAVA服务端实现页面截屏(附代码)

JAVA服务端实现页面截屏适配需求方案一、使用JxBrowser使用步骤&#xff1a;方案二、JavaFX WebView使用步骤&#xff1a;方案三、Headless Chrome使用步骤&#xff1a;综上方案对比记录我的一个失败方案参考适配需求 有正确完整的地址url&#xff1b;通过浏览器能打开该url对…...

Java入门要知道!

首先我们都知道的是Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表&#xff0c;极好地实现了面向…...

[6/101] 101次软件测试面试之经典面试题剖析

01、自我介绍答&#xff1a;大家好&#xff0c;我是一名软件测试工程师&#xff0c;但我更喜欢称自己为“软件bug捕手”。我相信&#xff0c;软件测试工程师的使命就是让软件更加健壮、更加可靠、更加美好。我们就像是一群“特警”&#xff0c;在黑暗的代码中寻找漏洞和缺陷&am…...

电脑c盘满了变成红色了怎么清理,清理c盘详细攻略

我们的电脑当用了一段时间之后&#xff0c;其实自然而然的就会有一点点卡&#xff0c;其实这是因为我们的电脑c盘满了&#xff0c;所以会造成卡顿是正常的&#xff0c;今天我们就来聊一聊电脑c盘满了变成红色了怎么清理&#xff1f; 一.电脑c盘为啥会满 软件安装&#xff1a;当…...

现在的00后,实在是太卷了

现在的小年轻真的卷得过分了。前段时间我们公司来了个00年的&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 最近和他聊了一次天&#xff0c;原来这位小老弟家里条…...

RocketMQ概述

RocketMQ入门学习MQ概述MQ简介MO用途限流削峰异步解耦数据收集常见的MQ产品ActiveMQRabbitMQKafkaRocketMQ对比MQ常见协议JMSSTOMPAMOPMQTTMQ概述 MQ简介 MQ&#xff0c;Message Queue&#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是…...

解决Ubuntu22.04.1上安装ch34x串口驱动报 Key was rejected by service 需要签名的问题

解决Ubuntu22.04.1上安装ch34x串口驱动报 Key was rejected by service 需要签名的问题问题官网下载解压驱动包编译安装给驱动签名再来载入模块&#xff08;设备驱动程序&#xff09;问题 Ubuntu22.04.1 Linux版本5.19.0-32-generic 运行Qt串口通信 m_serialPort->open(QIO…...

[python入门㊿] - python如何打断点

目录 ❤ 什么是bug(缺陷) ❤ python代码的调试方式 ❤ 使用 pdb 进行调试 测试代码示例 利用 pdb 调试 退出 debug debug 过程中打印变量 停止 debug 继续执行程序 debug 过程中显示代码 使用函数的例子 对函数进行 debug 在调试的时候动态改变值 ❤ 使用 PyC…...

CCNP350-401学习笔记(501-550题)

501、Refer to the exhibit. What is the effect of the configuration? A. The device will allow users at 192.168.0.202 to connect to vty lines 0 through 4 using the password ciscotestkey B. The device will allow only users at 192 168.0.202 to connect to vty …...

音箱上8键触摸芯片绿芯GTC08L完美替换启攀微

由工采网代理提供的韩国GreenChip电容式触摸芯片-GTC08L是GreenTouch5CTM电容式触摸传感器系列之一&#xff1b;可以在发动机运行下进行8通道电容传感&#xff1b;对电磁兼容、电磁干扰、温湿度变化、电压干扰、温度漂移、湿度漂移等都有较强的抗干扰能力。不会对CS, RS,EFT&am…...

php+vue加油站会员服务系统 java微信小程序

目 录 1绪论 1 1.1项目研究的背景 1 1.2开发意义 1 1.3项目研究现状及内容 5 1.4论文结构 5 2开发技术介绍 7 2.5微信小程序技术 8 3系统分析 9 3.1可行性分析 9 3.1.1技术可行性 9 3.1.2经济可行性 9 3.1.3操作可行性 10 3.2网站性能需求分析 10 3.3网站功能分析 10 3.4系统…...

ES6--class类(详解/看完必会)

目录 1、基本概念 2、基本用法 3、class与构造函数的区别 4、constructor的使用 5、自定义方法 6、extends和super &#xff08;1&#xff09;问题一&#xff1a;我们想要在点击按钮二的时候改变字体大小&#xff0c;如何写呢&#xff1f; &#xff08;2&#xff09;问…...

ChatGPT的出现网络安全专家是否会被替代?

ChatGPT的横空出世&#xff0c;在业界掀起了惊涛骇浪。很多人开始担心&#xff0c;自己的工作岗位是否会在不久的将来被ChatGPT等人工智能技术所取代。网络安全与先进技术发展密切相关&#xff0c;基于人工智能的安全工具已经得到很多的应用机会&#xff0c;那么未来是否更加可…...

游戏服务器框架设计 总纲

服务器框架篇&#xff1a; 1.配置文件系统 libxml 2.日志系统 log4xx 3.数据库保存以及接口设计 4.Proto协议定义 5.Redis接口设计 6.网络层设计 epoll/iocp 7.服务器内部协议路由层设计 8.分布式节点管理设计 9.服务器负载伸缩管理设计 10.服务器进程热更流程设计 11.GM系…...

PB里post提交

PB 通过 PostRul 一、 创建Standard Class对象 type为"internetresult" n_ir 二、 界面中,增加按钮。点击测试post提交。 Blob lblb_args String ls_header String ls_url String ls_args Long ll_length Integer li_rc inet iinet_base,iinet n_ir ir iinet_ba…...

Linux 配置网卡(基础配置、网卡会话配置、网卡绑定配置)

目录 配置网卡基本信息 通过nmcli命令配置网卡 通过配置网卡文件配置网卡 通过nmtui命令配置网卡 通过nm-connection-editor命令配置网卡 网卡高级配置 配置网络会话 配置网卡绑定&#xff08;Bonding&#xff09; 通过nmcli命令配置网卡绑定 nm-connection-editor 进…...

深度学习Week16-yolo.py文件解读(YOLOv5)

目录 简介 需要的基础包和配置 二、主要组件介绍 2.1 parse_model 2.2Detect类 2.3DetectionModel类 三、实验 &#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊…...

富文本编辑组件封装,tinymce、tinymce-vue

依赖&#xff1a;package.json yarn add tinymce tinymce/tinymce-vue {"dependencies": {"tinymce/tinymce-vue": "5.0.0","tinymce": "6.3.1","vue": "3.2.45",}, } 本地依赖&#xff1a; 在publ…...

电子作业指导书系统能树立良好的生产形象

“制造”就是以规定的成本、规定的工时、生产出品质均匀、符合规格的产品。从全球新能源汽车的发展来看&#xff0c;其动力电源主要包括锂离子电池、镍氢电池、铅酸电池、超级电容器&#xff0c;其中超级电容器大多以辅助动力源的形式出现。那么&#xff0c;电子作业指导书系统…...

Doris单机部署

文章目录1. 前言2. 安装3. 启动4. 使用1. 前言 Apache Doris 是一款现代 MPP (Massively Parallel Processing大规模并行处理) 的分布式 SQL 分析数据库&#xff0c;所谓分析数据库就是将其数据集分布在许多机器或节点上&#xff0c;以处理大量数据&#xff0c;采用 Apache 2.0…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周&#xff0c;有很多同学在写期末Java web作业时&#xff0c;运行tomcat出现乱码问题&#xff0c;经过多次解决与研究&#xff0c;我做了如下整理&#xff1a; 原因&#xff1a; IDEA本身编码与tomcat的编码与Windows编码不同导致&#xff0c;Windows 系统控制台…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

ffmpeg(四):滤镜命令

FFmpeg 的滤镜命令是用于音视频处理中的强大工具&#xff0c;可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下&#xff1a; ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜&#xff1a; ffmpeg…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...