hzleonardo hzleonardo - 7 months ago 224
Python Question

Selenium Screenshot Works Slow (Python)

Script with selenium and phantomjs which checks around 20 dynamic pages and warn me when there is a change works fast without screenshot part but when I want to get screenshots of the pages it takes around 1-2 minutes to warn me and to get screenshot. Is there a better and faster way to take screenshot of a specific part of page with python?

Here is the code I use for screenshot.

from selenium import webdriver
from PIL import Image

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
fox.save_screenshot('screenshot.png') # saves screenshot of entire page
fox.quit()

im = Image.open('screenshot.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



SOLVED:

The problem is not about selenium module, either screenshot. It is
about phantomjs, after I start using chromedriver it is very fast and more
efficent.

Answer

You could save some time by cropping the screenshot in memory without saving it first to a file:

import StringIO
from selenium import webdriver
from PIL import Image

driver = webdriver.Firefox()
driver.get('http://stackoverflow.com')
element = driver.find_element_by_id('hlogo')

crop_points = driver.execute_script("""
    var r = arguments[0].getBoundingClientRect();
    return [r.left, r.top, r.left + r.width, r.top + r.height];
    """, element)

with Image.open(StringIO.StringIO(driver.get_screenshot_as_png())) as img :
    with img.crop(crop_points) as imgsub :
        imgsub.save(logo.png', 'PNG')