百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

java如何网页截屏?selenium来搞定

csdh11 2024-12-26 12:26 15 浏览

背景

需求一直有,今年比较多,如题,工作中遇到网页截图这样的需求,本着效果好,功能全又稳定的意图,去网上搜索相关技术,像HTML2Image、cssbox、selenium等,还有很多其他的技术,这篇文章主要说说我测试使用并能满足需求的cssbox,selenium。

Cssbox

CSSBox是一个用纯Java编写的(X)HTML/CSS渲染引擎。它的主要目的是提供关于呈现的页面内容和布局的完整和进一步可处理的信息。 但是,它也可以用于浏览Java Swing应用程序中呈现的文档。核心CSSBox库还可以用于获得所呈现的文档的位图或矢量(SVG)图像。 使用SwingBox包,CSSBox可以用作Java Swing应用程序中的交互式Web浏览器组件。

官网地址:http://cssbox.sourceforge.net/

使用

1引入maven依赖

<!--网站转换为图片cssbox-->
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>cssbox</artifactId>
<version>5.0.0</version>
</dependency>

2使用

@Test
public void cssboxTest(){
    try {
        ImageRenderer render = new ImageRenderer();
        //网络链接的html
        String url = "https://www.zhangbj.com/p/524.html";
        //文件保存路径
        String path = "C:\\Users\\Administrator\\Desktop"+File.separator+"html.png";
        FileOutputStream out = new FileOutputStream(new File(FilenameUtils.normalize(path)));
        //开始截屏
        render.renderURL(url, out);
    } catch (Exception e) {
    e.printStackTrace();
    }
}

3结果

样式可能出现问题,中文有时候乱码

Selenium

1引入依赖

<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>

2相关准备

selenium+chromedriver谷歌驱动+chrome浏览器

1.注意谷歌驱动的版本要和谷歌浏览器的版本一样或者版本最相近

2.注意chromedriver谷歌驱动需要放在jdk安装目录下,具体路径为xxx/bin/chromedriver.exe,在linux和window中操作一样,这样切换系统是就无需改代码。

3.需要安装谷歌浏览器

谷歌驱动下载地址:https://registry.npmmirror.com/binary.html?path=chromedriver/

3使用

@Slf4j
public class Html2ImageUtil {
/**
* 将HTML转为图片,并保存至指定位置
* @param url 页面地址
* @param targetPath 保存地址(包含图片名,如 /images/test.png)
* @return
*/
public static String htmlToImage(String url, String targetPath) {
  if (StringUtils.isEmpty(url) || StringUtils.isEmpty(targetPath)) {
  throw new RuntimeException("截图失败!缺少必填项");
  }
  // 休眠时长
  Integer sleepTime = 3 * 1000;
  // 无头模式
  System.setProperty("java.awt.headless", "true");
  //获取谷歌配置信息
  ChromeOptions chromeOptions = getChromeOptions();
  // 配置信息中有默认窗口大小,也可以单独设置窗口大小
  chromeOptions.addArguments("--window-size=1920,6000");
  //创建webdriver 谷歌驱动
  WebDriver driver = new ChromeDriver(chromeOptions);
  //也可以通过如下方式设置窗口大小
  // Dimension dimension = new Dimension(1000, 30);
  // driver.manage().window().setSize(dimension);
  try {
    //加载页面
    driver.get(url);
    //等待加载页面
    Thread.sleep(sleepTime);
    //截屏
    File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    //保存到指定位置
    FileUtils.copyFile(srcFile, new File(FilenameUtils.normalize(targetPath)));
  } catch (InterruptedException | IOException e) {
  e.printStackTrace();
  throw new RuntimeException(e.getMessage());
  } finally {
  driver.quit();
  }
  log.info("截图成功!");
  return targetPath;
}
/**
* 获取chrome配置信息
* 注意 chromedriver谷歌驱动需要放在jdk安装目录下,具体路径为xxx/bin/chromedriver.exe ,在linux和window中操作一样
* @return
*/
public static ChromeOptions getChromeOptions() {
    ChromeOptions options = new ChromeOptions();
    //获取当前操作系统
    String os = System.getProperty("os.name");
    //获取jdk安装目录,需要提前将谷歌驱动放进jdk的bin目录下,在linux和window中操作一样
    String sysPath = System.getProperty("java.home").replace("jre", "bin");
    String chromeDriver = sysPath + File.separator+"chromedriver.exe";
    options.addArguments("disable-infobars");
    //设置为 headless 模式,不需要真实启动浏览器
    options.setHeadless(true);
    //options.addArguments("--headless");
    options.addArguments("--dns-prefetch-disable");
    options.addArguments("--no-referrers");
    options.addArguments("--disable-gpu");
    options.addArguments("--disable-audio");
    options.addArguments("--no-sandbox");
    options.addArguments("--ignore-certificate-errors");
    options.addArguments("--allow-insecure-localhost");
    options.addArguments("--window-size=1920,6000"); // 窗口默认大小
    String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36";
    userAgent = "user-agent=" + userAgent;
    options.addArguments(userAgent);
    // 设置chrome二进制文件
    options.setPageLoadStrategy(PageLoadStrategy.EAGER);
    // 设置驱动
    System.setProperty("webdriver.chrome.driver", chromeDriver);
    log.debug("结束获取chrome配置信息");
    return options;
}

测试

public static void main(String[] args) {
		htmlToImage("https://www.cnblogs.com/tester-ggf/p/12602211.html","C:\\Users\\Administrator\\Desktop\\aaa.png");
}

效果十分完美

总结

最完美的方案就是selenium+chromedriver谷歌驱动+chrome浏览器,无需多说,用吧。

您的赞和关注是对我创作的最大肯定谢谢大家!

相关推荐

探索Java项目中日志系统最佳实践:从入门到精通

探索Java项目中日志系统最佳实践:从入门到精通在现代软件开发中,日志系统如同一位默默无闻却至关重要的管家,它记录了程序运行中的各种事件,为我们排查问题、监控性能和优化系统提供了宝贵的依据。在Java...

用了这么多年的java日志框架,你真的弄懂了吗?

在项目开发过程中,有一个必不可少的环节就是记录日志,相信只要是个程序员都用过,可是咱们自问下,用了这么多年的日志框架,你确定自己真弄懂了日志框架的来龙去脉嘛?下面笔者就详细聊聊java中常用日志框架的...

物理老师教你学Java语言(中篇)(物理专业学编程)

第四章物质的基本结构——类与对象...

一文搞定!Spring Boot3 定时任务操作全攻略

各位互联网大厂的后端开发小伙伴们,在使用SpringBoot3开发项目时,你是否遇到过定时任务实现的难题呢?比如任务调度时间不准确,代码报错却找不到方向,是不是特别头疼?如今,随着互联网业务规模...

你还不懂java的日志系统吗 ?(java的日志类)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

谈谈枚举的新用法--java(java枚举的作用与好处)

问题的由来前段时间改游戏buff功能,干了一件愚蠢的事情,那就是把枚举和运算集合在一起,然后运行一段时间后buff就出现各种问题,我当时懵逼了!事情是这样的,做过游戏的都知道,buff,需要分类型,且...

你还不懂java的日志系统吗(javaw 日志)

一、背景在java的开发中,使用最多也绕不过去的一个话题就是日志,在程序中除了业务代码外,使用最多的就是打印日志。经常听到的这样一句话就是“打个日志调试下”,没错在日常的开发、调试过程中打印日志是常干...

Java 8之后的那些新特性(三):Java System Logger

去年12月份log4j日志框架的一个漏洞,给Java整个行业造成了非常大的影响。这个事情也顺带把log4j这个日志框架推到了争议的最前线。在Java领域,log4j可能相对比较流行。而在log4j之外...

Java开发中的日志管理:让程序“开口说话”

Java开发中的日志管理:让程序“开口说话”日志是程序员的朋友,也是程序的“嘴巴”。它能让程序在运行过程中“开口说话”,告诉我们它的状态、行为以及遇到的问题。在Java开发中,良好的日志管理不仅能帮助...

吊打面试官(十二)--Java语言中ArrayList类一文全掌握

导读...

OS X 效率启动器 Alfred 详解与使用技巧

问:为什么要在Mac上使用效率启动器类应用?答:在非特殊专业用户的环境下,(每天)用户一般可以在系统中进行上百次操作,可以是点击,也可以是拖拽,但这些只是过程,而我们的真正目的是想获得结果,也就是...

Java中 高级的异常处理(java中异常处理的两种方式)

介绍异常处理是软件开发的一个关键方面,尤其是在Java中,这种语言以其稳健性和平台独立性而闻名。正确的异常处理不仅可以防止应用程序崩溃,还有助于调试并向用户提供有意义的反馈。...

【性能调优】全方位教你定位慢SQL,方法介绍下!

1.使用数据库自带工具...

全面了解mysql锁机制(InnoDB)与问题排查

MySQL/InnoDB的加锁,一直是一个常见的话题。例如,数据库如果有高并发请求,如何保证数据完整性?产生死锁问题如何排查并解决?下面是不同锁等级的区别表级锁:开销小,加锁快;不会出现死锁;锁定粒度...

看懂这篇文章,你就懂了数据库死锁产生的场景和解决方法

一、什么是死锁加锁(Locking)是数据库在并发访问时保证数据一致性和完整性的主要机制。任何事务都需要获得相应对象上的锁才能访问数据,读取数据的事务通常只需要获得读锁(共享锁),修改数据的事务需要获...