How to take partial screenshot with Selenium WebDriver in python?

Other than Selenium, this example also requires the PIL Imaging library. Sometimes this is put in as one of the standard libraries and sometimes it's not, but if you don't have it you can install it with pip install Pillow

from selenium import webdriver
from PIL import Image
from io import BytesIO

fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')

# now that we have the preliminary stuff out of the way time to get that image :D
element = fox.find_element_by_id('hlogo') # find part of the page you want image of
location = element.location
size = element.size
png = fox.get_screenshot_as_png() # saves screenshot of entire page
fox.quit()

im = Image.open(BytesIO(png)) # uses PIL library to open image in memory

left = location['x']
top = location['y']
right = location['x'] + size['width']
bottom = location['y'] + size['height']


im = im.crop((left, top, right, bottom)) # defines crop points
im.save('screenshot.png') # saves new cropped image

and finally the output is... the Stackoverflow logo!!!

enter image description here

Now of course this would be overkill for just grabbing a static image but if your want to grab something that requires Javascript to get to this could be a viable solution.


Worked for me in python3.5

from selenium import webdriver


fox = webdriver.Firefox()
fox.get('http://stackoverflow.com/')
image = fox.find_element_by_id('hlogo').screenshot_as_png

p.s.

To save to file

image=driver.find_element_by_id('hlogo').screenshot(output_file_path)

I wrote this useful python3 function.

from base64 import b64decode
from wand.image import Image
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.common.action_chains import ActionChains
import math

def get_element_screenshot(element: WebElement) -> bytes:
    driver = element._parent
    ActionChains(driver).move_to_element(element).perform()  # focus
    src_base64 = driver.get_screenshot_as_base64()
    scr_png = b64decode(src_base64)
    scr_img = Image(blob=scr_png)

    x = element.location["x"]
    y = element.location["y"]
    w = element.size["width"]
    h = element.size["height"]
    scr_img.crop(
        left=math.floor(x),
        top=math.floor(y),
        width=math.ceil(w),
        height=math.ceil(h),
    )
    return scr_img.make_blob()

It returns png image of displayed element as bytes. Limitation: element must fit in viewport.
You must install wand module to work with it.


Here is a function that does just that, The sizes must be casted to integers before being passed to the crop function :

from PIL import Image
from StringIO import StringIO
def capture_element(element,driver):
  location = element.location
  size = element.size
  img = driver.get_screenshot_as_png()
  img = Image.open(StringIO(img))
  left = location['x']
  top = location['y']
  right = location['x'] + size['width']
  bottom = location['y'] + size['height']
  img = img.crop((int(left), int(top), int(right), int(bottom)))
  img.save('screenshot.png')