【问题标题】:How to get screenshot of full webpage using Selenium and Java?如何使用 Selenium 和 Java 获取完整网页的屏幕截图?
【发布时间】:2017-10-20 12:13:10
【问题描述】:

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

我的代码: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));

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

【问题讨论】:

  • 我有一个答案给你,但我想确认它是否适合你。那么您能否考虑详细说明full entire web page, not only partial from the top using selenium 的含义?谢谢

标签: java selenium selenium-webdriver webdriver screenshot


【解决方案1】:

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

有相当多的网络测试框架可以(只需最少的设置和工作)生成全页截图。我来自 NodeJS 测试环境,所以我只能保证以下几点:WebdriverIO & Google 的Puppeteer

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


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

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

  • 最大化窗口(使用--start-maximized 开关);
  • 全屏显示(Windows 上为F11-key,Mac 上为Control+Cmd+F,使用--start-fullscreen 开关)。
  • 注意:Chrome 命令行开关的完整列表可以在here 找到。

您的代码应如下所示:

// 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);

现在关于整页问题,所有驱动程序(chromedrivergeckodriverIEDriverEdgeDriver 等)都在执行WebDriver W3C 标准。因此,它们依赖于 WebDriver 团队想要公开不同特性的功能的方式,在我们的例子中,'Take Screenshot'

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

Take Screenshot 命令对顶级浏览上下文的 VIEWPORT 进行屏幕截图。

传统方面,一些驱动程序能够生成整页屏幕截图(阅读更多关于它here),如旧的 FirefoxDriver、IEDriver 等。现在不再是这种情况,因为它们现在都实现了(到字母)WebDriver W3C 标准。

【讨论】:

    【解决方案2】:
    File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("c:\\RESULT_FILENAME.png"));
    

    试试这个

    【讨论】:

    • 您是否花时间至少阅读了问题或他提供的片段?
    • 这个答案完全是题外话
    【解决方案3】:

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

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

    【讨论】:

    • 此代码在 Angujar js 应用程序中无法正常工作
    【解决方案4】:

    对于某些页面,我需要截取页面开头和结尾的屏幕截图。所以我习惯截取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));
    

    【讨论】:

      【解决方案5】:

      可以使用 Phantomjs 来实现。

      这是我的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();
              }
      
      
          }
      }
      

      因此您可以通过 Phantomjs 获取完整网页的屏幕截图。使用 Phantomjs 获取完整截图时,需要先下载 Phantomjs。然后运行 ​​Phantomjs 脚本进行截图。更多内容可以参考phantomjs.org

      【讨论】:

      • @Pierre.Vriens 对不起,我的英语不好。我想表达的是你可以通过 Phantomjs 获取完整网页的截图。使用 Phantomjs 获取完整截图时,需要先下载 Phantomjs,然后运行 ​​Phantomjs 脚本进行截图。更多内容可以参考phantomjs.org
      • PhantomJS 已被at least two years 弃用,并正式存档since early 2018。停止使用生命周期结束或缺乏适当支持的软件。此外,自从 --headless 切换到 Chrome 以及在无头浏览器中投入大量的 Chromium 努力后,像 PhantomJS 这样的第三方项目已经过时,因此该项目被放弃了......
      【解决方案6】:

      看起来像 article 建议 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();
              }
          }
      

      【讨论】:

        【解决方案7】:

        这是我使用 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();
        

        【讨论】:

          【解决方案8】:

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

          由于您的无头浏览器的高度不依赖于您的显示器尺寸,您可以使用这种无头模式来获取在 Chrome 浏览器中呈现的全长屏幕截图。

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

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

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

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

          【讨论】:

            【解决方案9】:

            不使用第三方库的Java代码:

            int bodyHeight = webDriver.findElement(By.tagName("body")).getSize().getHeight();
            int windowChromeHeight = (int) (long) webDriver.executeScript("return window.outerHeight - window.innerHeight");
            Dimension size = new Dimension(webDriver.manage().window().getSize().getWidth(), bodyHeight + windowChromeHeight);
            webDriver.executeScript("window.scrollTo(0, 0);");
            webDriver.manage().window().setSize(size);
                        
            File screenshotFile = new File("screenshot.png");
            Files.write(screenshotFile.toPath(), webDriver.getScreenshotAs(OutputType.BYTES));
            

            【讨论】:

              【解决方案10】:

              现在有了使用 Selenium 4 和 Firefox 的简单方法。

              byte[] imageBytes = ((FirefoxDriver)driver).getFullPageScreenshotAs(OutputType.BYTES);
              Files.write(Paths.get(RESULT_FILENAME), imageBytes);
              

              其他浏览器尚不支持getFullPageScreenshotAs()

              【讨论】:

              • 这是否适用于“acrobat.adobe.com”的整页截图?对我来说,我只得到一个小视口,而不是整页。
              • 是的,“acrobat.adobe.com”的整页屏幕截图适用于 Selenium 4 beta 2。
              • 啊,我必须使用 Thread.sleep(5000) 来加载页面,现在可以使用了。
              • 没有多少睡眠可以帮助我正确呈现页面。一些元素看起来奇怪地被截断了。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2023-01-23
              • 1970-01-01
              • 2012-10-26
              • 1970-01-01
              • 2017-12-25
              • 1970-01-01
              • 2017-02-28
              相关资源
              最近更新 更多