Java根据url生成图片、截图效果

 更新时间:2025年01月26日 11:41:12   作者:c740ab-9199-accf3bcc  
文章详细介绍了如何使用Java和Node.js结合Puppeteer库根据URL截图,并将图片转换为标准输出流返回给Java程序,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧

Java根据url截图 说明原理环境准备如何使用集成

说明

来都来了,别着急走,有些搞后端的同志看到使用了nodejs头也不回的就走了,我也是纯后端出身,接下来的内容和安装步骤我会以后端入门级开发都能看懂方式描述,简易程度堪比Hello Word

原理

nodejs可以直接在cmd命令窗格中通过命令直接运行,Java可以调用命令窗格执行某个命令;

使用nodejs脚本调用Puppeteer(Puppeteer是一个由Google Chrome团队官方提供的Node.js库)利用Puppeteer无感的调用Chrome浏览器抓取网页并截图,最后将图片转为标准输出流返给Java程序

环境准备

1.确保已经安装了node和npm运行环境

node -v
npm -v

可以执行上面的两个命令来检查,能看到输出版本号,表示环境没问题;如果没有安装可以访问nodejs官网,下载安装程序 傻瓜式下一步安装即可;安装完成后将镜像地址改成国内的

npm config set registry https://registry.npmmirror.com

2.确保安装了Chrome浏览器或基于Chrome内核开发的浏览器

如何使用

1.创建文件夹,打开cmd cd到新建的文件中执行下面的命令,这个过程大概需要3-5分钟

npm install puppeteer

执行完后的效果如下

2.新建screenshot.js文件,编写nodejs脚本

const puppeteer = require('puppeteer');
// 获取java传过来的参数
const url = process.argv[2];
(async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    // 设置视口大小
    await page.setViewport({
        width: 1920,
        height: 1080,
        deviceScaleFactor: 2, // 像素比,默认为 1。在高 DPI 屏幕上,可以将其设置为 2 或更高,以模拟高分辨率显示。
    });
    await page.goto(url);
    const screenshotBuffer = await page.screenshot({
        fullPage: true;//是否截全屏
    });
    // 输出截图的 Buffer 到标准输出流
    process.stdout.write(screenshotBuffer);
    await browser.close();
})();

效果如下

3.cmd在当前目录中执行下面的命令,测试抓取百度的页面

node screenshot.js https://www.baidu.com/

抓取成功后的效果
一堆乱码对吧,但是不要慌 这是正常的,因为脚本中是将文件流转成了标准的输出流

4.Java代码

package com.assoft.erms.common.utils;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
public class ScreenshotUtil {
    public static void main(String[] args) {
        //js脚本文件地址
        String screenshotJs = "D:\\workspace\\javascript\\screenshot.js";
        //要截图的网页(有拦截器,需要验证身份的不行)
        String url = "http://politics.people.com.cn/n1/2024/1031/c1024-40350705.html";
        //保存的文件名
        String filePath = "screenshot.png";
        try {
            //两种返回类型,逻辑是一样的;只是返回类型不同 根据情况自行选择
            // 模式一:获取截图的字节数组
            byte[] screenshotBytes = ScreenshotUtil.captureScreenshotAsBytes(url,screenshotJs);
            System.out.println("屏幕截图字节数组长度: " + screenshotBytes.length);
            // 模式二:将截图保存到指定路径
            ScreenshotUtil.captureScreenshotAsFile(url, filePath,screenshotJs);
            System.out.println("屏幕截图已保存到: " + filePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 获取网页截图的字节数组
     * @param url
     * @return
     * @throws Exception
     */
    public static byte[] captureScreenshotAsBytes(String url,String screenshotJs) throws Exception {
        Process process = Runtime.getRuntime().exec(new String[]{"node", screenshotJs, url});
        // 获取 Process 的输入流
        try (InputStream inputStream = process.getInputStream();
             ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, length);
            }
            process.waitFor(); // 等待进程结束
            return byteArrayOutputStream.toByteArray(); // 返回字节数组
        }
    }
    /**
     * 将网页截图保存到指定路径
     * @param url
     * @param filePath
     * @throws Exception
     */
    public static void captureScreenshotAsFile(String url, String filePath,String screenshotJs) throws Exception {
        byte[] screenshotBytes = captureScreenshotAsBytes(url,screenshotJs); // 获取截图字节数组
        // 将字节数组写入文件
        try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) {
            fileOutputStream.write(screenshotBytes);
        }
    }
}

5.最终的效果图如下

图片违规了。。。。

集成

Demo是写好了,怎么集成到自己的java工程中呢?

很简单只需要将node_modules和screenshot.js复制到自己的Java工程中,package.json、package-lock.json不需要

目录层级的说明:
screenshot.js会往上查找node_modules,以下是三个例子

可行

|-- node_modules
|-- screenshot.js

可行

|-- node_modules
|-- js
	|-- screenshot.js

不可行

|-- screenshot.js
|-- static
	|-- node_modules

到此这篇关于Java根据url生成图片、截图的文章就介绍到这了,更多相关java根据url生成图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java中关于移位运算符的demo与总结(推荐)

    java中关于移位运算符的demo与总结(推荐)

    下面小编就为大家带来一篇java中关于移位运算符的demo与总结(推荐)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • Java数据结构之双向链表的实现

    Java数据结构之双向链表的实现

    相较单链表,双向链表除了data与next域,还多了一个pre域用于表示每个节点的前一个元素。这样做给双向链表带来了很多优势。本文主要介绍了双向链表的实现,需要的可以参考一下
    2022-10-10
  • log4j2日志异步打印(实例讲解)

    log4j2日志异步打印(实例讲解)

    下面小编就为大家带来一篇log4j2日志异步打印(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • Idea中添加Maven项目支持scala的详细步骤

    Idea中添加Maven项目支持scala的详细步骤

    这篇文章主要介绍了Idea中添加Maven项目支持scala,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • Java  Thread多线程详解及用法解析

    Java Thread多线程详解及用法解析

    本文主要介绍Java 多线程详解及用法,这里整理了详细资料及简单实现代码,有需要的小伙伴可以参考下
    2016-09-09
  • skywalking分布式服务调用链路追踪APM应用监控

    skywalking分布式服务调用链路追踪APM应用监控

    这篇文章主要为大家介绍了skywalking分布式服务调用链路追踪APM应用监控的功能使用说明,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-03-03
  • Java 8中日期和时间的处理方法

    Java 8中日期和时间的处理方法

    Java 8新增了LocalDate和LocalTime接口,接下来通过本文给大家介绍Java 8中日期和时间的处理方法,非常不错,感兴趣的朋友一起看下吧
    2016-08-08
  • 全面解析Java main方法

    全面解析Java main方法

    main方法是我们学习Java语言学习的第一个方法,也是每个java使用者最熟悉的方法,每个Java应用程序都必须有且仅有一个main方法。这篇文章通过实例代码给大家介绍java main方法的相关知识,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-05-05
  • Java查询MongoDB数据库案例大全

    Java查询MongoDB数据库案例大全

    这篇文章主要给大家介绍了关于Java查询MongoDB数据库的一些相关案例,Java可以使用MongoDB的官方Java驱动程序来连接和操作MongoDB数据库,需要的朋友可以参考下
    2023-07-07
  • Spring Boot读取配置文件内容的3种方式(@Value、Environment和@ConfigurationProperties)

    Spring Boot读取配置文件内容的3种方式(@Value、Environment和@ConfigurationP

    工作中经常会有一些参数需要配置,同时在代码里面需要用到,所有就需要配置类读取,然后在使用的时候注入该类进行获取相关参数,下面这篇文章主要给大家介绍了关于Spring Boot读取配置文件内容的3种方式,需要的朋友可以参考下
    2023-01-01

最新评论