java-生成浏览器截长图

java 生成浏览器截长图

项目中有需要用到截网页图片的功能

技术方案

使用 selenium 结合 chrome 模拟浏览器打开网页,然后对网页进行截图保存

实现

引入依赖
<dependency>
    <groupId>ru.yandex.qatools.ashot</groupId>
    <artifactId>ashot</artifactId>
    <version>1.5.4</version>
</dependency>
<!--selenium-java 版本要和chrome一致-->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.20.0</version>
</dependency>
<dependency>
下载浏览器驱动
  • 查看chrome版本
    • 在chrome浏览器地址栏输入: chrome://version/, 我这里是 124版本
  • 下载驱动
代码实现
package com.icmp.dt.datongbak.banner;

import cn.hutool.core.io.FileUtil;
import com.sun.source.doctree.SeeTree;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.WebDriverWait;
import ru.yandex.qatools.ashot.AShot;
import ru.yandex.qatools.ashot.Screenshot;
import ru.yandex.qatools.ashot.coordinates.WebDriverCoordsProvider;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

/**
 * @Date: 2024/4/28 14:28
 */
@Slf4j
public class ChromeCapture {

    // webdriver驱动解压位置
    private static final String DRIVER_URL = "E:\\chromedriver-win64\\chromedriver.exe";

    private static  WebDriver driver = null;

    static {
        ChromeOptions options = new ChromeOptions();
        //无头,不在操作系统上打开chrome应用
        options.addArguments("--headless");
        //options.addArguments("--disable-gpu");
        options.addArguments("--no-sandbox");
        driver = new ChromeDriver(options);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().window().maximize();
    }

    public static void main(String[] args) throws InterruptedException {
        fullScreenShotPng("",new File("a.PNG"));
        quit();
    }

    /**
     * 截PNG长图
     * @param url
     * @param file
     * @throws InterruptedException
     */
    public static void fullScreenShotPng(String url,File file) throws InterruptedException {
        fullScreenShot(url,300,500L,file,"PNG");
    }

        /**
         * 截长图
         * @param url  网页地址
         * @param rollingDistance 300 滚动距离
         * @param waitTime 500 毫秒
         * @param file 保存文件
         * @throws InterruptedException
         */
    public static void fullScreenShot(String url,int rollingDistance,Long waitTime,File file, String suffix) throws InterruptedException {
        System.setProperty("webdriver.chrome.driver",DRIVER_URL);

        try {

            driver.get(url);
            //等待页面加载完成
            new WebDriverWait(driver, Duration.ofSeconds(20)).until(drive -> ((JavascriptExecutor) drive)
                    .executeScript("return document.readyState").equals("complete"));
            // 设置小的分辨率
            //driver.manage().window().setSize(new Dimension(1920, 1080));
            JavascriptExecutor je = (JavascriptExecutor) driver;
            // 通过执行脚本解决Selenium截图不全问题
            String jsHeight = "return document.body.clientHeight";
            int height = Integer.parseInt(je.executeScript(jsHeight)+"");

            // 滚动次数
            int frequency = height % rollingDistance == 0 ? height / rollingDistance : height / rollingDistance + 1;
            for (int i = 0; i < frequency; i++) {

                int length = i * rollingDistance;
                Thread.sleep(waitTime);
                ((JavascriptExecutor) driver).executeScript("window.scrollTo(0," + length + ")");
            }

            //设置浏览窗口大小
            int maxWidth = Integer.parseInt(je.executeScript(
                    "return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement" +
                            ".clientWidth, document.documentElement.scrollWidth, document.documentElement" +
                            ".offsetWidth);")+"");
            int maxHeight = Integer.parseInt(je.executeScript(
                    "return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement" +
                            ".clientHeight, document.documentElement.scrollHeight, document.documentElement" +
                            ".offsetHeight);")+"");
            Dimension targetSize = new Dimension((int)maxWidth, (int)maxHeight);
            driver.manage().window().setSize(targetSize);

            // 重新拉到页面顶端
            ((JavascriptExecutor) driver).executeScript("window.scrollTo(document.body.scrollHeight,0)");

            // 截图
            Screenshot screenshot = new AShot().coordsProvider(new WebDriverCoordsProvider()).takeScreenshot(driver);
            BufferedImage image = screenshot.getImage();
            ImageIO.write(image, suffix, file);
        } catch (Exception e) {

            log.error("快照失败: {}",url, e);
        }
    }

    public static void quit(){
        if (driver!=null){
            driver.quit();
        }
    }
}

截图效果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些指导。以下是一些实现步骤: 1. 创建GUI窗口和JLabel组件 您可以使用Swing或JavaFX创建窗口和JLabel组件。这里以Swing为例: ```java JFrame frame = new JFrame("浏览器"); JLabel imageLabel = new JLabel(); frame.add(imageLabel); frame.pack(); frame.setVisible(true); ``` 2. 获取片列表 您可以使用Java的File类来获取指定目录下的所有片文件。以下是一个示例: ```java File dir = new File("path/to/images"); File[] files = dir.listFiles(new FilenameFilter() { public boolean accept(File dir, String name) { return name.toLowerCase().endsWith(".jpg") || name.toLowerCase().endsWith(".png"); } }); ``` 3. 加载像 您可以使用Java的ImageIO类来加载像。以下是一个示例: ```java BufferedImage image = ImageIO.read(files[index]); ``` 其中,index是当前要显示的片在文件列表中的索引。 4. 设置像到JLabel 您可以使用JLabel的setIcon()方法来设置像。以下是一个示例: ```java imageLabel.setIcon(new ImageIcon(image)); ``` 5. 添加导航按钮 您可以添加“上一张”和“下一张”按钮来允许用户在片列表中进行导航。当用户单击这些按钮时,您可以更新当前要显示的片的索引并重新加载像。以下是一个示例: ```java JButton prevButton = new JButton("上一张"); prevButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (index > 0) { index--; try { BufferedImage image = ImageIO.read(files[index]); imageLabel.setIcon(new ImageIcon(image)); } catch (IOException ex) { ex.printStackTrace(); } } } }); JButton nextButton = new JButton("下一张"); nextButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (index < files.length - 1) { index++; try { BufferedImage image = ImageIO.read(files[index]); imageLabel.setIcon(new ImageIcon(image)); } catch (IOException ex) { ex.printStackTrace(); } } } }); frame.add(prevButton, BorderLayout.WEST); frame.add(nextButton, BorderLayout.EAST); ``` 希望这些步骤能对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值