【问题标题】:How to take full page Screenshot of a scrollable webpage using Selenium WebDriver with Java?如何使用 Selenium WebDriver 和 Java 获取可滚动网页的整页截图?
【发布时间】:2017-03-23 10:33:02
【问题描述】:

仅对可见屏幕进行屏幕截图的现有代码。我正在使用Chromedriver

  System.setProperty("webdriver.chrome.driver", "D:/chromedriver/chromedriver.exe");
  WebDriver driver = new ChromeDriver();
  driver.get("http://www.bbc.com");       
  driver.manage().window().maximize();
  System.out.println(driver.getTitle());
  File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
  FileUtils.copyFile(scrFile, new File("D:/chromedriver/scr3.png"));
  driver.close();

【问题讨论】:

  • 我猜这是不可能的,因为 selenium 可能只能与可见的网络元素交互。
  • 能否手动截取因滚动条而无法显示的页面?因为要查看页面的那些部分,您需要手动滚动。如果没有,那么如何使用 selenium 实现它?
  • @ShoaibAkhtar selenium IDE 有一个命令(captureEntirePageScreenshot),它可以截取整页(可滚动页面)的屏幕截图,那么为什么不能在 webdriver 中实现它
  • @SarthakSrivastava 该图像上的滚动条是否可以滚动?您想生成带有滚动条的屏幕截图,并且您应该能够在该屏幕截图中滚动滚动条。我猜这就是你的要求。如果是,那么我认为即使在 Selenium IDE 中使用 captureEntirePageScreenshot 也是不可能的。还是您的要求是别的?

标签: java selenium selenium-webdriver screenshot


【解决方案1】:

请找到以下代码,您可以滚动并截取任意数量的屏幕截图。注意elements Web 元素。存储它们并相对滚动。 您可以根据想要的屏幕截图数量滚动。

driver.get("http://www.bbc.com");       
driver.manage().window().maximize();
System.out.println(driver.getTitle());
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("D:/chromedriver/scr3.png"));  
WebElement elements = driver.findElement(By.xpath(".//*[@id='page']/section[6]/div/div/div[1]/ul/li[3]/div/div[2]/h3/a"));    
Thread.sleep(3000L);
JavascriptExecutor js = (JavascriptExecutor) driver;
int yPosition = elements.getLocation().getY();
js.executeScript("window.scroll (0, " + yPosition + ") ");       
Thread.sleep(3000L);         
File scrFile1 = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile1, new File("D:/chromedriver/scr4.png"));
driver.close();

【讨论】:

  • 你有一个解决方案,只有一个 olny png 文件(合并)?
【解决方案2】:

你不能仅仅使用硒来做到这一点。您需要其他工具来执行您的任务。点开链接看看我的回答:Screen shot issue in selenium webdriver

希望对你有帮助。

【讨论】:

    【解决方案3】:

    要截取完整网页的屏幕截图,我们必须使用名为“aShot”的第三方实用程序。 aShot 是一个 WebDriver Schreenshot 实用程序,我们可以使用它截取整个网页以及单个 WebElement。为此,我们必须下载 aShot jar 文件并与 Selenium jar 文件一起添加到我们的项目中。

    【讨论】:

      【解决方案4】:

      你可以试试这个方法。希望它会有用:-

      public static void takeFullPageScreenShot(WebDriver driver) throws IOException {
      
          JavascriptExecutor jsExec = (JavascriptExecutor)driver;
      
          jsExec.executeScript("window.scrollTo(0, 0);"); //Scroll To Top
      
          Long innerHeight = (Long) jsExec.executeScript("return window.innerHeight;");
          Long scroll = innerHeight;
      
          Long scrollHeight = (Long) jsExec.executeScript("return document.body.scrollHeight;"); 
      
          scrollHeight = scrollHeight + scroll;
      
          do{
      
              File screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
      
              //Unique File Name For Each Screenshot
              File destination = new File("E://screenshots//"+String.join("_", 
              LocalDateTime.now().toString().split("[^A-Za-z0-9]"))+".jpg");
      
              FileUtils.copyFile(screenshot, destination));
      
              jsExec.executeScript("window.scrollTo(0, "+innerHeight+");");
      
              innerHeight = innerHeight + scroll;
      
          }while(scrollHeight >= innerHeight);
      }
      
      
      Or,
        File screenshot = 
        driver.findElement(By.tagName("body")).getScreenshotAs(OutputType.FILE);
        File destination = new File("E://screenshots//"+String.join("_", 
        LocalDateTime.now().toString().split("[^A-Za-z0-9]"))+".jpg");
        FileUtils.copyFile(screenshot, destination));
      

      【讨论】:

        【解决方案5】:

        使用Shutterbug,又短又甜:

        public byte[] shootPage() throws IOException {
            BufferedImage image = Shutterbug.shootPage(driver, ScrollStrategy.WHOLE_PAGE).getImage();
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            ImageIO.write(image, "png", outputStream);
            return outputStream.toByteArray();
        }
        

        【讨论】:

          【解决方案6】:

          试试这个代码。 AB D 的上述回应有一些逻辑错误。它们在下面得到解决:

          public static void takeFullPageScreenShot(WebDriver driver) throws IOException {
          
              JavascriptExecutor jsExec = (JavascriptExecutor)driver;
          
              //Returns a Long, Representing the Height of the window’s content area.
              Long windowHeight = (Long) jsExec.executeScript("return window.innerHeight;");
          
              //Returns a Long, Representing the Height of the complete WebPage a.k.a. HTML document.
              Long webpageHeight = (Long) jsExec.executeScript("return document.body.scrollHeight;"); 
          
              //Marker to keep track of the current position of the scroll point
              //Long currentWindowScroll = Long.valueOf(0);
              //Using java's boxing feature to create a Long object from native long value.
          
              Long currentWindowScroll = 0L;
          
              do{
                  //System.out.println(windowHeight + ", " + webpageHeight + ", " + currentWindowScroll);
          
                  jsExec.executeScript("window.scrollTo(0, " + currentWindowScroll + ");");
          
                  Actions act = new Actions(driver);
                  act.pause(5000).perform();
          
                  File tempScreenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
          
                  //Unique File Name For Each Screenshot
                  File destination = new File("C:\\core_java\\DemoScreenShot\\" + String.join("_", LocalDateTime.now().toString().split("[^A-Za-z0-9]"))+ ".png");
          
                  Files.copy(tempScreenshot, destination);
                  currentWindowScroll = currentWindowScroll + windowHeight;
          
              }while(currentWindowScroll <= webpageHeight);
          }
          

          【讨论】:

            【解决方案7】:

            在 Selenium 4 中,FirefoxDriver 提供了一个处理垂直和水平滚动以及固定元素(例如导航栏)的 getFullPageScreenshotAs 方法。其他驱动程序尚无此功能。

            System.setProperty("webdriver.gecko.driver", "path/to/geckodriver");
            final FirefoxOptions options = new FirefoxOptions();
            // set options...
            final FirefoxDriver driver = new FirefoxDriver(options);
            driver.get("https://stackoverflow.com/");
            File fullScreenshotFile = driver.getFullPageScreenshotAs(OutputType.FILE);
            // File will be deleted once the JVM exits, so you should copy it
            

            【讨论】:

              【解决方案8】:

              这是@kwishna 的回答的一个进步,它将屏幕截图拼接成一个图像:

                  public void takeFullPageScreenShot(WebDriver driver) throws IOException {
                      JavascriptExecutor jsExec = (JavascriptExecutor) driver;
                      jsExec.executeScript("window.scrollTo(0, 0);");
                      Long innerHeight = (Long) jsExec.executeScript("return window.innerHeight;");
                      Long scroll = innerHeight;
                      Long scrollHeight = (Long) jsExec.executeScript("return document.body.scrollHeight;");
              
                      scrollHeight = scrollHeight + scroll;
              
                      List<byte[]> images = new ArrayList<>();
              
                      do {
                          byte[] screenshot = ((TakesScreenshot)driver).getScreenshotAs(OutputType.BYTES);
                          images.add(screenshot);
                          jsExec.executeScript("window.scrollTo(0, "+innerHeight+");");
                          innerHeight = innerHeight + scroll;
                      } while (scrollHeight >= innerHeight);
              
                      BufferedImage result = null;
                      Graphics g = null;
              
                      int x = 0, y = 0;
                      for(byte[] image : images){
                          InputStream is = new ByteArrayInputStream(image);
                          BufferedImage bi = ImageIO.read(is);
                          if (result == null) {
                              // Lazy init so we can infer height and width
                              result = new BufferedImage(
                                      bi.getWidth(), bi.getHeight() * images.size(),
                                      BufferedImage.TYPE_INT_RGB);
                              g = result.getGraphics();
                          }
                          g.drawImage(bi, x, y, null);
                          y += bi.getHeight();
                      }
                      ImageIO.write(result,"png",new File("result.png"));
                  }
              

              【讨论】:

                猜你喜欢
                • 2023-03-09
                • 2017-10-20
                • 2020-01-29
                • 2023-01-23
                • 2012-10-26
                • 1970-01-01
                • 2014-11-10
                • 2017-02-10
                • 2019-01-24
                相关资源
                最近更新 更多