如何使用 Selenium 和 Java 获取完整网页的屏幕截图?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/44085722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 01:18:52  来源:igfitidea点击:

How to get screenshot of full webpage using Selenium and Java?

javaseleniumselenium-webdriverwebdriverscreenshot

提问by Placinta Alexandru

How to take a screenshot of the entire web page (full-page screenshot), not only partial (top-to-bottom) using Selenium WebDriver?

如何使用 Selenium WebDriver截取整个网页的屏幕截图(整页屏幕截图),而不仅仅是部分(从上到下)?

My code:(Java bindings)

我的代码:Java 绑定

System.setProperty("webdriver.chrome.driver","/home/alex/Downloads/chromedriver_linux64/chromedriver");
WebDriver driver = new ChromeDriver();
driver.get("http://google.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File(RESULT_FILENAME));

Any ideas on how to tackle this?

关于如何解决这个问题的任何想法?

采纳答案by iamdanchiv

LE:I see quite a lot of people are interested in the full-page screenshot, so I thought I might update the answer with some positives (silver bullets).

LE:我看到很多人对整页截图感兴趣,所以我想我可能会用一些积极的东西来更新答案(银弹)。

There are quite a handful of web testing frameworks that can (with minimal setup & effort) produce a full-page screenshot. I come from a NodeJS testing environment, so I can only vouch the following: WebdriverIO& Google's Puppeteer.

有很多 Web 测试框架可以(以最少的设置和努力)生成整页屏幕截图。我来自 NodeJS 测试环境,所以我只能保证以下内容:WebdriverIO和 Google 的Puppeteer

If anyone is interested in an easy way to do it with WebdriverIO, check thisanswer.

如果有人对使用 WebdriverIO 的简单方法感兴趣,请查看答案。



Short answer is NO, YOU CANNOT, if you're only using Selenium(detailed reason bellow). But, what you can do is make the most out of your device's(monitor) viewport.

简短的回答是否定的,你不能如果你只使用 Selenium(详细原因如下)。但是,您可以做的是充分利用设备的(监视器)视口

So, start your browser instance (driver) using ChromeOptions(), which is the method for setting ChromeDriver-specific capabilities. We can do the following:

因此,使用 启动浏览器实例(驱动程序)ChromeOptions(),这是设置 ChromeDriver 特定功能的方法。我们可以执行以下操作:

  • maximize the window (using the --start-maximizedswitch);
  • go full-screen (F11-key on Windows, Control+Cmd+Fon Mac, using the --start-fullscreenswitch).
  • Note: complete list of Chrome command-line-switches can be found here.
  • 最大化窗口(使用--start-maximized开关);
  • 全屏显示(F11WindowsControl+Cmd+F上的-key,Mac 上,使用--start-fullscreen开关)。
  • 注意:可以在此处找到 Chrome 命令行开关的完整列表。

Your code should look like this:

您的代码应如下所示:

// Setting your Chrome options (Desired capabilities)
ChromeOptions options = new ChromeOptions();
options.add_argument('--start-maximized');
options.add_argument('--start-fullscreen');

// Creating a driver instance with the previous capabilities
WebDriver driver = new ChromeDriver(options);

// Load page & take screenshot of full-screen page
driver.get("http://google.com");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

Now regarding the full page problem, all drivers (chromedriver, geckodriver, IEDriver, EdgeDriver, etc.) are implementing the WebDriver W3Cstandard. Thus, they are dependent on the way the WebDriver team wants to expose the functionality of different features, in our case, 'Take Screenshot'.

现在关于整版的问题,所有的驱动程序(chromedrivergeckodriverIEDriverEdgeDriver,等)正在实施的webdriver W3C标准。因此,它们取决于 WebDriver 团队希望公开不同特性的功能的方式,在我们的例子中,“截取屏幕截图”

If you read the definition, it clearly states the following:

如果您阅读定义,它会清楚地说明以下内容:

The Take Screenshot command takes a screenshot of the top-level browsing context's VIEWPORT.

Take Screenshot 命令获取顶级浏览上下文的VIEWPORT的屏幕截图。

Legacy-wise, some drivers were able to produce a full-page screenshot (read more about it here), like the old FirefoxDriver, IEDriver, etc. That is no longer the case as they now all implement (to the letter) the WebDriver W3C standard.

传统方面,一些驱动程序能够生成整页屏幕截图(在此处阅读更多相关信息),例如旧的 FirefoxDriver、IEDriver 等。现在情况不再如此,因为它们现在都实现了(完全符合)WebDriver W3C 标准。

回答by padmini

File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\RESULT_FILENAME.png"));

Try this

尝试这个

回答by Krzysztof Walczewski

I have found a tutorial http://www.softwaretestingmaterial.com/how-to-capture-full-page-screenshot-using-selenium-webdriver/For maven users: remember about adding dependendency from https://mvnrepository.com/artifact/ru.yandex.qatools.ashot/ashotWhen I testing this script, I've got large pictures, which can't be open in browser (too large or broken).

我找到了一个教程http://www.softwaretestingmaterial.com/how-to-capture-full-page-screenshot-using-selenium-webdriver/对于 maven 用户:记得从https://mvnrepository.com/添加依赖项artifact/ru.yandex.qatools.ashot/ashot当我测试这个脚本时,我有大图片,无法在浏览器中打开(太大或损坏)。

So maybe someone know any script, which focus page on last used locator?

所以也许有人知道任何脚本,上次使用的定位器的哪个焦点页面?

回答by Krzysztof Walczewski

For some pages I neeed to take screenshot of begin and end of page. So I use to take 2 screenshots:

对于某些页面,我需要截取页面开头和结尾的屏幕截图。所以我用来截取 2 个屏幕截图:

public static String javaIoTmpDir = System.getProperty("java.io.tmpdir"); //tmp dir
//create screenshot
    driver.manage().window().fullscreen();
    //For large pages - body over 850 px highh - take addition screenshot of the end of page
    if (driver.findElements(By.id("panel_body")).size()>0) {
        WebElement body = driver.findElement(By.id("panel_body"));
        int bodyHight = body.getSize().getHeight();
        if (bodyHight > 850) {
            Robot robot = new Robot();
            robot.keyPress(KeyEvent.VK_END);
            robot.keyRelease(KeyEvent.VK_END);
            Thread.sleep(1000);
            File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
            String timePictureEnd = javaIoTmpDir+"\scr_"+String.valueOf(System.currentTimeMillis())+getClass().toString().substring(getClass().toString().lastIndexOf(".qa.")+3)+".png";
            FileUtils.copyFile(scrFile, new File(timePictureEnd));
            robot.keyPress(KeyEvent.VK_HOME); //back to top page for next screen
            robot.keyRelease(KeyEvent.VK_HOME);
            Thread.sleep(1000);
        }
    }
    String timePicture = javaIoTmpDir+"\scr_"+String.valueOf(System.currentTimeMillis())+getClass().toString().substring(getClass().toString().lastIndexOf(".qa.")+3)+".png";
    File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File(timePicture));

回答by H.Dayday

You can use Phantomjs to achieve it.

您可以使用 Phantomjs 来实现它。

Here is my java code:

这是我的Java代码:

public class PhantomjsTest {
    public static void main(String[] args) {
        try {

            long start=System.currentTimeMillis();
            //The page you want to screenshot
            String targetUrl="https://www.iqiyi.com/";
            //File path
            String targetImg="iqiyi.png";
            String command = "/Users/hetiantian/SoftWares/phantomjs/bin/phantomjs /Users/hetiantian/SoftWares/phantomjs/examples/rasterize.js "+targetUrl + " " +targetImg;
            Process p = Runtime.getRuntime().exec(command);
            p.waitFor();
            System.out.println((System.currentTimeMillis()-start));
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}

So you can get a screenshot of full webpage by Phantomjs. When you use Phantomjs to get a full screenshot, you need to download Phantomjs first. Then run Phantomjs script to screenshot. More about it you can reference phantomjs.org.

所以你可以通过 Phantomjs 获得完整网页的截图。使用 Phantomjs 获取完整截图时,需要先下载 Phantomjs。然后运行 ​​Phantomjs 脚本进行截图。更多关于它你可以参考phantomjs.org

回答by Wenzhong Hu

Looks like this articlesuggesting AShotworks for me. Also, I successfully embeded the full page screenshot into Cucumber report with following code

看起来这篇文章建议AShot对我有用。另外,我使用以下代码成功地将整页屏幕截图嵌入到 Cucumber 报告中

    scenario.embed(takeScreenShotAsByte(getWebDriver()), "image/png");

    private static byte[] takeScreenShotAsByte(WebDriver webDriver) throws IOException {
        return takeFullPageScreenShotAsByte(webDriver);
    }

    private static byte[] takeFullPageScreenShotAsByte(WebDriver webDriver) throws IOException {
        Screenshot fpScreenshot = new AShot().shootingStrategy(ShootingStrategies.viewportPasting(1000))
                .takeScreenshot(webDriver);

        BufferedImage originalImage = fpScreenshot.getImage();

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(originalImage, "png", baos);
            baos.flush();
            return baos.toByteArray();
        }
    }

回答by Andre Fernandes Luiz

Here is my sample of get Full Screen ScreenShot using C#, but just change:

这是我使用 C# 获取全屏截图的示例,但只需更改:

            string _currentPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(One of your objects)).Location) + @"\Attachs\";
            var filePath = _currentPath + sSName;

            if (!Directory.Exists(_currentPath))
                Directory.CreateDirectory(_currentPath);

            Dictionary<string, Object> metrics = new Dictionary<string, Object>();
            metrics["width"] = _driver.ExecuteScript("return Math.max(window.innerWidth,document.body.scrollWidth,document.documentElement.scrollWidth)");
            metrics["height"] = _driver.ExecuteScript("return Math.max(window.innerHeight,document.body.scrollHeight,document.documentElement.scrollHeight)");
            metrics["deviceScaleFactor"] = (double)_driver.ExecuteScript("return window.devicePixelRatio");
            metrics["mobile"] = _driver.ExecuteScript("return typeof window.orientation !== 'undefined'");
            _driver.ExecuteChromeCommand("Emulation.setDeviceMetricsOverride", metrics);

            _driver.GetScreenshot().SaveAsFile(filePath, ScreenshotImageFormat.Png);

            _driver.ExecuteChromeCommand("Emulation.clearDeviceMetricsOverride", new Dictionary<string, Object>());
            _driver.Close();

回答by Talmtikisan

It is possible to start Chrome in headless mode and then set the window size to the same height of the page body.

可以在无头模式下启动 Chrome,然后将窗口大小设置为与页面正文相同的高度。

Since the height of your headless browser is not dependent on your monitor size you can use this headless mode to get full length screenshots as they are rendered in the Chrome browser.

由于无头浏览器的高度与显示器尺寸无关,因此您可以使用此无头模式获取在 Chrome 浏览器中呈现的全长屏幕截图。

The top answer for Headless Chrome run with seleniumseems to show the right way to start Chrome in headless mode with java. I work with python bindings but the answer looks pretty similar to what I do.

使用 selenium 运行 Headless Chrome的最佳答案似乎显示了使用 java 以无头模式启动 Chrome 的正确方法。我使用 python 绑定,但答案看起来与我所做的非常相似。

This is the relevant part. This code should go before you start an instance of ChromeDriver.

这是相关的部分。此代码应该在您启动 ChromeDriver 实例之前运行。

ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("--headless");

ChromeDriver driver = new ChromeDriver(chromeOptions);

If running chrome in a headless browser is not a viable option then you'll have to use Firefox or IE. Both of these browsers will give you a full length screenshot

如果在无头浏览器中运行 chrome 不是一个可行的选择,那么您将不得不使用 Firefox 或 IE。这两种浏览器都会为您提供完整的屏幕截图