Java根據(jù)url生成圖片、截圖效果
Java根據(jù)url截圖 說明原理環(huán)境準(zhǔn)備如何使用集成
說明
來都來了,別著急走,有些搞后端的同志看到使用了nodejs頭也不回的就走了,我也是純后端出身,接下來的內(nèi)容和安裝步驟我會(huì)以后端入門級(jí)開發(fā)都能看懂方式描述,簡(jiǎn)易程度堪比Hello Word
原理
nodejs可以直接在cmd命令窗格中通過命令直接運(yùn)行,Java可以調(diào)用命令窗格執(zhí)行某個(gè)命令;
使用nodejs腳本調(diào)用Puppeteer(Puppeteer是一個(gè)由Google Chrome團(tuán)隊(duì)官方提供的Node.js庫(kù))利用Puppeteer無感的調(diào)用Chrome瀏覽器抓取網(wǎng)頁并截圖,最后將圖片轉(zhuǎn)為標(biāo)準(zhǔn)輸出流返給Java程序
環(huán)境準(zhǔn)備
1.確保已經(jīng)安裝了node和npm運(yùn)行環(huán)境
node -v npm -v
可以執(zhí)行上面的兩個(gè)命令來檢查,能看到輸出版本號(hào),表示環(huán)境沒問題;如果沒有安裝可以訪問nodejs官網(wǎng),下載安裝程序 傻瓜式下一步安裝即可;安裝完成后將鏡像地址改成國(guó)內(nèi)的
npm config set registry https://registry.npmmirror.com
2.確保安裝了Chrome瀏覽器或基于Chrome內(nèi)核開發(fā)的瀏覽器
如何使用
1.創(chuàng)建文件夾,打開cmd cd到新建的文件中執(zhí)行下面的命令,這個(gè)過程大概需要3-5分鐘
npm install puppeteer
執(zhí)行完后的效果如下
2.新建screenshot.js文件,編寫nodejs腳本
const puppeteer = require('puppeteer'); // 獲取java傳過來的參數(shù) const url = process.argv[2]; (async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // 設(shè)置視口大小 await page.setViewport({ width: 1920, height: 1080, deviceScaleFactor: 2, // 像素比,默認(rèn)為 1。在高 DPI 屏幕上,可以將其設(shè)置為 2 或更高,以模擬高分辨率顯示。 }); await page.goto(url); const screenshotBuffer = await page.screenshot({ fullPage: true;//是否截全屏 }); // 輸出截圖的 Buffer 到標(biāo)準(zhǔn)輸出流 process.stdout.write(screenshotBuffer); await browser.close(); })();
效果如下
3.cmd在當(dāng)前目錄中執(zhí)行下面的命令,測(cè)試抓取百度的頁面
node screenshot.js https://www.baidu.com/
抓取成功后的效果
一堆亂碼對(duì)吧,但是不要慌 這是正常的,因?yàn)槟_本中是將文件流轉(zhuǎn)成了標(biāo)準(zhǔn)的輸出流
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"; //要截圖的網(wǎng)頁(有攔截器,需要驗(yàn)證身份的不行) String url = "http://politics.people.com.cn/n1/2024/1031/c1024-40350705.html"; //保存的文件名 String filePath = "screenshot.png"; try { //兩種返回類型,邏輯是一樣的;只是返回類型不同 根據(jù)情況自行選擇 // 模式一:獲取截圖的字節(jié)數(shù)組 byte[] screenshotBytes = ScreenshotUtil.captureScreenshotAsBytes(url,screenshotJs); System.out.println("屏幕截圖字節(jié)數(shù)組長(zhǎng)度: " + screenshotBytes.length); // 模式二:將截圖保存到指定路徑 ScreenshotUtil.captureScreenshotAsFile(url, filePath,screenshotJs); System.out.println("屏幕截圖已保存到: " + filePath); } catch (Exception e) { e.printStackTrace(); } } /** * 獲取網(wǎng)頁截圖的字節(jié)數(shù)組 * @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(); // 等待進(jìn)程結(jié)束 return byteArrayOutputStream.toByteArray(); // 返回字節(jié)數(shù)組 } } /** * 將網(wǎng)頁截圖保存到指定路徑 * @param url * @param filePath * @throws Exception */ public static void captureScreenshotAsFile(String url, String filePath,String screenshotJs) throws Exception { byte[] screenshotBytes = captureScreenshotAsBytes(url,screenshotJs); // 獲取截圖字節(jié)數(shù)組 // 將字節(jié)數(shù)組寫入文件 try (FileOutputStream fileOutputStream = new FileOutputStream(filePath)) { fileOutputStream.write(screenshotBytes); } } }
5.最終的效果圖如下
圖片違規(guī)了。。。。
集成
Demo是寫好了,怎么集成到自己的java工程中呢?
很簡(jiǎn)單只需要將node_modules和screenshot.js復(fù)制到自己的Java工程中,package.json、package-lock.json不需要
目錄層級(jí)的說明:
screenshot.js會(huì)往上查找node_modules,以下是三個(gè)例子
可行
|-- node_modules |-- screenshot.js
可行
|-- node_modules |-- js |-- screenshot.js
不可行
|-- screenshot.js |-- static |-- node_modules
到此這篇關(guān)于Java根據(jù)url生成圖片、截圖的文章就介紹到這了,更多相關(guān)java根據(jù)url生成圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java中關(guān)于移位運(yùn)算符的demo與總結(jié)(推薦)
下面小編就為大家?guī)硪黄猨ava中關(guān)于移位運(yùn)算符的demo與總結(jié)(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-05-05Java數(shù)據(jù)結(jié)構(gòu)之雙向鏈表的實(shí)現(xiàn)
相較單鏈表,雙向鏈表除了data與next域,還多了一個(gè)pre域用于表示每個(gè)節(jié)點(diǎn)的前一個(gè)元素。這樣做給雙向鏈表帶來了很多優(yōu)勢(shì)。本文主要介紹了雙向鏈表的實(shí)現(xiàn),需要的可以參考一下2022-10-10Idea中添加Maven項(xiàng)目支持scala的詳細(xì)步驟
這篇文章主要介紹了Idea中添加Maven項(xiàng)目支持scala,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03skywalking分布式服務(wù)調(diào)用鏈路追蹤APM應(yīng)用監(jiān)控
這篇文章主要為大家介紹了skywalking分布式服務(wù)調(diào)用鏈路追蹤APM應(yīng)用監(jiān)控的功能使用說明,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03Java查詢MongoDB數(shù)據(jù)庫(kù)案例大全
這篇文章主要給大家介紹了關(guān)于Java查詢MongoDB數(shù)據(jù)庫(kù)的一些相關(guān)案例,Java可以使用MongoDB的官方Java驅(qū)動(dòng)程序來連接和操作MongoDB數(shù)據(jù)庫(kù),需要的朋友可以參考下2023-07-07Spring?Boot讀取配置文件內(nèi)容的3種方式(@Value、Environment和@ConfigurationP
工作中經(jīng)常會(huì)有一些參數(shù)需要配置,同時(shí)在代碼里面需要用到,所有就需要配置類讀取,然后在使用的時(shí)候注入該類進(jìn)行獲取相關(guān)參數(shù),下面這篇文章主要給大家介紹了關(guān)于Spring?Boot讀取配置文件內(nèi)容的3種方式,需要的朋友可以參考下2023-01-01