Java+Selenium实现网页截图

概述

使用Java语言,实现网页截图。本文仅考虑Selenium方案,如果对其他方案感兴趣,可参考Java实现HTML页面截图功能

实现

大名鼎鼎的自动化测试工具,引入最新稳定版依赖:

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

直接上代码:

public static void snapshotBySelenium(String url) {
	// 根据系统来添加不同的驱动路径
	String os = System.getProperty("os.name");
    if (StrUtil.containsIgnoreCase(os, ArmConstant.WINDOWS)) {
        System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
    } else {
    	// 只考虑Linux环境,需要下载对应版本的驱动后放置在绝对路径/usr/bin目录下
        System.setProperty("webdriver.chrome.driver", "/usr/bin/chromedriver");
    }
    try {
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--headless");
        options.addArguments("--disable-gpu");
        options.addArguments("--no-sandbox");

        ChromeDriver driver = new ChromeDriver(options);
        driver.manage().window().maximize();
        driver.get(url);
        String jsHeight = "return document.body.clientHeight";
        long height = (long) driver.executeScript(jsHeight);
        int k = 1;
        int size = 500;
        while (k * size < height) {
            String jsMove = String.format("window.scrollTo(0,%s)", k * 500);
            driver.executeScript(jsMove);
            Thread.sleep(100);
            height = (long) driver.executeScript(jsHeight);
            k += 1;
        }

		// 通过执行脚本解决Selenium截图不全问题
        long maxWidth = (long) driver.executeScript(
                "return Math.max(document.body.scrollWidth, document.body.offsetWidth, document.documentElement.clientWidth, document.documentElement.scrollWidth, document.documentElement.offsetWidth);");
        long maxHeight = (long) driver.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);

        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        String strTime = sdf.format(date);

        File img = driver.getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(img, new File(strTime + ".png"));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

问题

部分可以打开的网站截图失败,显示为白屏或者黑屏,如:
https://www.nifa.org.cn/nifa/2955675/2955761/2974440/index.html
截图效果:
在这里插入图片描述
诸般尝试,都告以失败。

想到之前手动使用FireShot插件实现网页截图。FireShot可以说是Chrome浏览器必备插件,参考关于Chrome浏览器的一些使用技巧

而Selenium是支持添加插件执行自动化测试。想当然以为options是通过addExtensions()方法来添加插件,下面代码里面File目录可以有两种方式查询得知:

  1. 通过使用search everything全局搜索FireShot
  2. 打开chrome://extensions/,搜索FireShot,得到chrome://extensions/?id=mcbpblocgmgfnpjjppndjkmgjaogfceg,然后去Chrome安装盘定位,得到目录,需要对Chrome的安装目录有较深理解:
options.addExtensions(new File("C:\\Users\\cheng\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\mcbpblocgmgfnpjjppndjkmgjaogfceg\\0.99.1_0"));

结果一直报错:
java.lang.IllegalArgumentException: C:\Users\cheng\AppData\Local\Google\Chrome\User Data\Default\Extensions\mcbpblocgmgfnpjjppndjkmgjaogfceg\0.99.1_0 is a directory

实际上,Selenium添加插件有两种方式:

使用离线插件形式

必须通过addExtensions()方法,指向本地已经下载的离线插件:

options.addExtensions(new File("D:\\迅雷下载\\FireShot\\FireShot.crx"));
ChromeDriver driver = new ChromeDriver(options);

注意,使用离线版本的插件之前,可以先校验一下插件的版本和自己当前安装的Chrome版本是否适配,地址栏打开chrome://extensions,然后把下载的.crx文件拖进来,如果出现下面的报错,说明版本不适配:
在这里插入图片描述
事实上,通过代码也可以发现版本不适配的问题:

SessionNotCreatedException: session not created: cannot process extension #1
from unknown error: CRX verification failed to parse extension header. Chrome supports only CRX3 format. Does the extension need to be updated?

下载一个更新版本的插件:

options.addExtensions(new File("D:\\迅雷下载\\FireShot_0.98.97.2_chrome.zzzmh.cn.crx"));

报错:

org.openqa.selenium.WebDriverException: unknown error: failed to wait for extension background page to load: chrome-extension://mcbpblocgmgfnpjjppndjkmgjaogfceg/_generated_background_page.html
from unknown error: page could not be found: chrome-extension://mcbpblocgmgfnpjjppndjkmgjaogfceg/_generated_background_page.html

上面报错信息里面mcbpblocgmgfnpjjppndjkmgjaogfceg正好就是我Chrome安装的FireShot唯一ID。

怎么就失败呢?

  1. 禁用已经安装并启用的插件:
    在这里插入图片描述
    重试,失败。
  2. 删除本地文件夹mcbpblocgmgfnpjjppndjkmgjaogfceg,重试失败。
  3. 看到插件页有一个查看试图—背景页链接:
    在这里插入图片描述
    打开之后:
    在这里插入图片描述
    右键,另存为,放到本地目录C:\\Users\\cheng\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\mcbpblocgmgfnpjjppndjkmgjaogfceg\\0.99.1_0下面,重试,依旧不行。

Chrome无界面浏览模式与自定义插件加载问题,该篇文章指出两种是不兼容的,没有很好的解决方法。

既然如此,那去掉options.addArguments("--headless");这一行参数配置,不报错。

但是截图依然失败。。。

百度及google,给出的一个值得尝试的stackoverflow-方案:弃用Chrome,使用Firefox。

加载本地已经安装的插件

必须通过addArguments()方法,来加载指定的插件:
options.addArguments("load-extension=C:\\Users\\cheng\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Extensions\\mcbpblocgmgfnpjjppndjkmgjaogfceg\\0.99.1_0");

HTML页面截图成功。Wait?

问题

这种方式,怎么适用于Linux系统??

参考

Selenium启动Chrome插件(Chrome Extensions)

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是使用JavaSelenium和TestNG编写登录网页测试案例的示例代码: ```java import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; public class LoginTest { private WebDriver driver; @BeforeClass public void setup() { // 设置ChromeDriver路径 System.setProperty("webdriver.chrome.driver", "path/to/chromedriver"); // 创建一个Chrome浏览器实例 driver = new ChromeDriver(); } @Test public void testLogin() { // 打开登录页面 driver.get("https://example.com/login"); // 输入用户名和密码 WebElement usernameField = driver.findElement(By.id("username")); WebElement passwordField = driver.findElement(By.id("password")); WebElement loginButton = driver.findElement(By.id("login-button")); usernameField.sendKeys("username"); passwordField.sendKeys("password"); // 点击登录按钮 loginButton.click(); // 验证登录是否成功 WebElement welcomeMessage = driver.findElement(By.id("welcome-message")); Assert.assertEquals(welcomeMessage.getText(), "欢迎回来!"); } @AfterClass public void teardown() { // 关闭浏览器 driver.quit(); } } ``` 这个测试案例使用Chrome浏览器打开一个登录页面,输入用户名和密码,然后点击登录按钮。接着,它验证登录是否成功,通过检查页面上的欢迎消息来实现。最后,它关闭浏览器。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

johnny233

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值