5 Best Ways to Take Partial Screenshot with Selenium WebDriver in Python

Rate this post

πŸ’‘ Problem Formulation: Frequently in test automation, there is a need to capture screenshots of only part of a webpage rather than its entirety. One might need to capture a specific element or a section on the page to validate visual features or to log them for debugging purposes. The desired input is the locator of the web element you wish to capture, and the output is the screenshot saved to a file.

Method 1: Using PIL to Crop the Screenshot

This method involves taking a full-page screenshot with Selenium and then using the Python Imaging Library (PIL), now known under the name ‘Pillow’, to crop it to the desired area. The coordinates for the area are specified relative to the fullscreen image.

Here’s an example:

from selenium import webdriver
from PIL import Image

driver = webdriver.Chrome()
driver.get('https://www.example.com')
element = driver.find_element_by_id('element-id')

full_screenshot = 'full_screenshot.png'
partial_screenshot = 'partial_screenshot.png'
driver.save_screenshot(full_screenshot)

image = Image.open(full_screenshot)
left = element.location['x']
top = element.location['y']
right = element.location['x'] + element.size['width']
bottom = element.location['y'] + element.size['height']

image.crop((left, top, right, bottom)).save(partial_screenshot)

The output is a file named ‘partial_screenshot.png’ with only the specified element’s screenshot.

This code initiates a webdriver, navigates to a website, and locates the element by its ID. It then takes a full-page screenshot and saves it. Using the PIL library, it crops the screenshot to the element’s dimensions and saves the result to a separate file.

Method 2: JavaScript and Canvas for Element Screenshot

Capture an element’s screenshot by employing the browser’s canvas via injected JavaScript. This method directly grabs the desired element’s image without the need for cropping afterward, which is helpful when dealing with complex page layouts.

Here’s an example:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.example.com')
element = driver.find_element_by_id('element-id')

js_script = "var canvas = document.createElement('canvas');\
var ctx = canvas.getContext('2d');\
ctx.drawImage(arguments[0], 0, 0);\
return canvas.toDataURL('image/png').substring(22);"
img = driver.execute_script(js_script, element)

with open("element_screenshot.png", "wb") as file:
    file.write(bytes(img, 'utf-8'))

The output is a file named ‘element_screenshot.png’ containing the desired element’s screenshot.

This approach injects a JavaScript snippet that creates a canvas element in the browser, draws the target element onto it, and then converts it into a data URL. The image is then written to a file in PNG format.

Method 3: Screenshot of a Scrollable Element

A challenging scenario emerges when dealing with elements that can be scrolled internally. This method will capture the displayed portion of the scrollable element. It assumes that the element is already in view.

Here’s an example:

from selenium import webdriver
driver = webdriver.Chrome()
driver.get('https://www.example.com')
scrollable_element = driver.find_element_by_id('scrollable-element-id')

screenshot = 'scrollable_element_screenshot.png'
scrollable_element.screenshot(screenshot)

The output is an image file named ‘scrollable_element_screenshot.png’ which is a screenshot of the visible area of the scrollable element.

In Selenium 4 and newer, the element.screenshot(filename) method can be called directly on a web element, making it simple to take a screenshot of a scrollable element without any additional cropping.

Method 4: Screenshot of a Fixed Region

In some cases, you may want to take a screenshot of a fixed region specified by pixel coordinates. This method is useful when you’re interested in a specific part of the webpage that does not correspond to a particular element, or when element locations may vary.

Here’s an example:

from selenium import webdriver
from PIL import Image

driver = webdriver.Chrome()
driver.get('https://www.example.com')

full_screenshot = 'full_screenshot.png'
fixed_region_screenshot = 'fixed_region_screenshot.png'
driver.save_screenshot(full_screenshot)

image = Image.open(full_screenshot)
region = (50, 50, 200, 200) # left, upper, right, lower
image.crop(region).save(fixed_region_screenshot)

The output is a file named ‘fixed_region_screenshot.png’ with a screenshot of the specified fixed region.

This method first captures a full page screenshot and then uses PIL to crop the image to the supported fixed-region coordinates.

Bonus One-Liner Method 5: Direct Element Screenshot with Selenium 4

As of Selenium 4, it’s possible to take a screenshot of a specific page element directly. This one-liner method is the most straightforward when working with the latest version of Selenium.

Here’s an example:

driver.find_element_by_id('element-id').screenshot('element_screenshot.png')

The output is an image file named ‘element_screenshot.png’ which is a screenshot of the targeted element.

This concise code line directs the driver to find the element by its ID and immediately save a screenshot of it. It leverages the new feature provided in Selenium 4 that allows directly capturing an element’s screenshot without any intermediate steps.

Summary/Discussion

  • Method 1: PIL to Crop the Screenshot. Strengths: Precise and versatile. Weaknesses: Requires additional PIL library, overhead of saving a full-page screenshot first.
  • Method 2: JavaScript and Canvas. Strengths: Direct screenshot without post-processing, complex layout handling. Weaknesses: Involves JavaScript execution, more complex setup.
  • Method 3: Screenshot of a Scrollable Element. Strengths: Simple and quick with newer Selenium versions. Weaknesses: Limited to the visible area of scrollable elements.
  • Method 4: Screenshot of a Fixed Region. Strengths: Useful for static areas. Weaknesses: Not tied to DOM elements, may require adjustments if page layout changes.
  • Bonus Method 5: Direct Element Screenshot with Selenium 4. Strengths: Extremely easy and efficient with Selenium 4. Weaknesses: Only available in recent Selenium versions.