How to take partial screenshot (frame) with Selenium WebDriver?

后端 未结 5 1810
不思量自难忘°
不思量自难忘° 2020-12-05 01:06

Is it possible to take a screenshot with WebDriver of only one frame (not the complete window) within a frameset?

Alternatively, is it possible to define coordinate

相关标签:
5条回答
  • 2020-12-05 01:15

    Python solution (dependency: PIL or Pillow):

    from PIL import Image
    from selenium import webdriver
    
    def element_screenshot(driver, element, filename):
        bounding_box = (
            element.location['x'], # left
            element.location['y'], # upper
            (element.location['x'] + element.size['width']), # right
            (element.location['y'] + element.size['height']) # bottom
        )
        return bounding_box_screenshot(driver, bounding_box, filename)
    
    def bounding_box_screenshot(driver, bounding_box, filename):
        driver.save_screenshot(filename)
        base_image = Image.open(filename)
        cropped_image = base_image.crop(bounding_box)
        base_image = base_image.resize(cropped_image.size)
        base_image.paste(cropped_image, (0, 0))
        base_image.save(filename)
        return base_image
    
    if __name__ == '__main__':
        driver = webdriver.Firefox()
        driver.get('https://www.google.com/?gws_rd=ssl')
        element = driver.find_element_by_id('body')
    
        screenshot = element_screenshot(driver, element, 'element.png') # Screenshot the '#body' element
    
        bounding_box = (100, 100, 600, 600)
        screenshot = bounding_box_screenshot(driver, bounding_box, 'box.png') # Screenshot the bounding box (100, 100, 600, 600)
    
    0 讨论(0)
  • 2020-12-05 01:16

    Just posting a solution based on C# on taking a specific Html element's screenshot in selenium:

    First we need to take the screen shot of entire web page using the GetScreenShot method of selenium web driver as below.

    Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot(); 
    screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
    

    Then create a rectangle from the location , height and width of the specified html element. (This has to be obtained using FindElement() method of selenium by providing id or class name).

    Image img = Bitmap.FromFile(uniqueName);
    Rectangle rect = new Rectangle();
    
    if (element != null)
    {
        // Get the Width and Height of the WebElement using
        int width = element.Size.Width;
        int height = element.Size.Height;
    
        // Get the Location of WebElement in a Point.
        // This will provide X & Y co-ordinates of the WebElement
        Point p = element.Location;
    
        // Create a rectangle using Width, Height and element location
        rect = new Rectangle(p.X, p.Y, width, height);
    }
    

    Using this we are going to crop the the screenshot as below and the result will be the screenshot specific web element.

    Bitmap bmpImage = new Bitmap(img);
    var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);
    

    Full code as a method below:

    /// <summary>
    /// Captures the element screen shot.
    /// </summary>
    /// <param name="element">The element.</param>
    /// <param name="uniqueName">Name of the unique.</param>
    /// <returns>returns the screenshot  image </returns>
    public Image CaptureElementScreenShot(HTMLElement element, string uniqueName)
    {
        Screenshot screenshot = ((ITakesScreenshot)this.driver).GetScreenshot();
        screenshot.SaveAsFile(filename, System.Drawing.Imaging.ImageFormat.Jpeg);
    
        Image img = Bitmap.FromFile(uniqueName);
        Rectangle rect = new Rectangle();
    
        if (element != null)
        {
            // Get the Width and Height of the WebElement using
            int width = element.Size.Width;
            int height = element.Size.Height;
    
            // Get the Location of WebElement in a Point.
            // This will provide X & Y co-ordinates of the WebElement
            Point p = element.Location;
    
            // Create a rectangle using Width, Height and element location
            rect = new Rectangle(p.X, p.Y, width, height);
        }
    
        // croping the image based on rect.
        Bitmap bmpImage = new Bitmap(img);
        var cropedImag = bmpImage.Clone(rect, bmpImage.PixelFormat);
    
        return cropedImag;
    }
    
    0 讨论(0)
  • 2020-12-05 01:23

    Ruby solution

    Setup

    Install xvfb

    apt-get install xvfb -y
    

    Install headless browser and image manipulation gem

    gem install chunky_png
    gem install headless
    gem install selenium-webdriver
    

    Install chrome driver

    wget http://chromedriver.googlecode.com/files/chromedriver_linux64_<latest>.zip
    apt-get install unzip
    unzip chromedriver_linux64_<latest>.zip
    cp chromedriver /usr/local/bin
    

    More info can be found here

    Code

    #!/usr/bin/env ruby
    
    require "headless"
    require "selenium-webdriver"
    require 'chunky_png'
    
    headless = Headless.new
    headless.start
    
    site = "?_some_site_?"
    
    driver = Selenium::WebDriver.for :chrome
    driver.navigate.to site
    sleep 1
    driver.save_screenshot('screenshot.png')
    
    el= driver.find_element(:xpath, '?_some_xpath_?')
    
    image = ChunkyPNG::Image.from_file('screenshot.png')
    
    image.crop!(el.location.x + 1, el.location.y + 1, el.size.width, el.size.height)
    image.save('croped.png')
    
    driver.quit
    headless.destroy
    
    0 讨论(0)
  • 2020-12-05 01:24

    Scala solution:

    import javax.imageio.ImageIO
    import java.awt.image.BufferedImage
    
    // phone is a case class with witdth and height Int fields
    
    def producer {       
     [..]
     processScreenshot(driver.getScreenshotAs(OutputType.FILE), ph)
    }
    
    def processScreenshot(file: File, phone: Phone) = {
     val img: BufferedImage = ImageIO.read(file)
     val w = math.min(img.getWidth, phone.width)
     val h = math.min(img.getHeight, phone.height)
     val dest = img.getSubimage(0, 0, w, h)
     ImageIO.write(dest, "png", new File(s"/tmp/${un}_${phone.file}.png"))
    }
    
    0 讨论(0)
  • 2020-12-05 01:26

    This should work:

    import java.awt.image.BufferedImage;
    import java.io.File;
    
    import javax.imageio.ImageIO;
    
    import org.openqa.selenium.By;
    import org.openqa.selenium.OutputType;
    import org.openqa.selenium.Point;
    import org.openqa.selenium.TakesScreenshot;
    import org.openqa.selenium.WebDriver;
    
    public class Shooter{
    
        private WebDriver driver;
    
        public void shootWebElement(WebElement element) throws IOException  {
    
            File screen = ((TakesScreenshot) this.driver).getScreenshotAs(OutputType.FILE);
    
            Point p = element.getLocation();
    
            int width = element.getSize().getWidth();
            int height = element.getSize().getHeight();
    
            BufferedImage img = ImageIO.read(screen);
    
            BufferedImage dest = img.getSubimage(p.getX(), p.getY(), width,   
                                     height);
    
            ImageIO.write(dest, "png", screen);
    
            File f = new File("S:\\ome\\where\\over\\the\\rainbow");
    
            FileUtils.copyFile(screen, f);
    
        }
    }
    
    0 讨论(0)
提交回复
热议问题