Webdriver Screenshot in Python
Asked Answered
V

15

73

When taking a screenshot using Selenium Webdriver on windows with python, the screenshot is saved directly to the path of the program, is there a way to save the .png file to a specific directory?

Vagal answered 17/1, 2012 at 18:55 Comment(0)
V
91

Use driver.save_screenshot('/path/to/file') or driver.get_screenshot_as_file('/path/to/file'):

import selenium.webdriver as webdriver
import contextlib

@contextlib.contextmanager
def quitting(thing):
    yield thing
    thing.quit()

with quitting(webdriver.Firefox()) as driver:
    driver.implicitly_wait(10)
    driver.get('http://www.google.com')
    driver.get_screenshot_as_file('/tmp/google.png') 
    # driver.save_screenshot('/tmp/google.png')
Vesuvianite answered 17/1, 2012 at 19:3 Comment(4)
Hi, driver.save_screenshot('/path/to/file') works on Windows, but driver.get_screenshot_as_file('/path/to/file') doesn't. (Yes, I changed for "\\"). But it helped, thank you. Have you got any idea guys how to check google's ReCaptcha with selenium? You will not be able to select any elements, even if HTML generates <div class="google-recaptcha"> or whatever... JS Scripts does not work too. For clarification, I do not mean solving images in reCaptcha, but only checking a checkbox "Im not a robot".Renascence
@TommyL: save_screenshot calls get_screenshot_as_file, so if one worked, so should the other.Vesuvianite
@TommyL: Regarding recaptcha -- try googling something like "selenium click google recaptcha". There are a number of potential leads, such as this one. If that doesn't work for you, you could consider posting a new question -- including your code so we understand what you've tried and what went wrong.Vesuvianite
One more thing that helped me immensely, if you need to change the image dimension, simply set the window size before you take the snapshot using driver.set_window_size(1366, 728)Hagfish
C
35

Inspired from this thread (same question for Java): Take a screenshot with Selenium WebDriver

from selenium import webdriver

browser = webdriver.Firefox()
browser.get('http://www.google.com/')
browser.save_screenshot('screenie.png')
browser.quit()
Cisterna answered 16/12, 2013 at 12:23 Comment(0)
W
11

Yes, we have a way to get screenshot extension of .png using python webdriver

use below code if you working in python webriver.it is very simple.

driver.save_screenshot('D\folder\filename.png')
Whine answered 13/12, 2012 at 8:31 Comment(0)
B
7
driver.save_screenshot("path to save \\screen.jpeg")
Bichromate answered 8/5, 2015 at 7:44 Comment(0)
F
7

This will take screenshot and place it in a directory of a chosen name.

import os
driver.save_screenshot(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'NameOfScreenShotDirectory', 'PutFileNameHere'))
Fluoride answered 27/6, 2018 at 14:35 Comment(3)
It's great to have a nicely formatted code for the answer but it's usually best practice to include a little explanation with it.Anadromous
"This will take screenshot and place it in a directory of a chosen name." is pretty clear for most people I'd imagineFluoride
NameError: name 'file' is not definedScooter
S
6

Here they asked a similar question, and the answer seems more complete, I leave the source:

How to take partial screenshot with Selenium WebDriver in python?

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
Supposal answered 7/6, 2018 at 20:50 Comment(0)
F
5

Sure it isn't actual right now but I faced this issue also and my way: Looks like 'save_screenshot' have some troubles with creating files with space in name same time as I added randomization to filenames for escaping override.

Here I got method to clean my filename of whitespaces (How do I replace whitespaces with underscore and vice versa?):

def urlify(self, s):
    # Remove all non-word characters (everything except numbers and letters)
    s = re.sub(r"[^\w\s]", '', s)
    # Replace all runs of whitespace with a single dash
    s = re.sub(r"\s+", '-', s)
    return s

then

driver.save_screenshot('c:\\pytest_screenshots\\%s' % screen_name)

where

def datetime_now(prefix):
    symbols = str(datetime.datetime.now())
    return prefix + "-" + "".join(symbols)

screen_name = self.urlify(datetime_now('screen')) + '.png'
Friesland answered 6/5, 2015 at 10:23 Comment(0)
B
3

You can use below function for relative path as absolute path is not a good idea to add in script

Import

import sys, os

Use code as below :

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
screenshotpath = os.path.join(os.path.sep, ROOT_DIR,'Screenshots'+ os.sep)
driver.get_screenshot_as_file(screenshotpath+"testPngFunction.png")

make sure you create the folder where the .py file is present.

os.path.join also prevent you to run your script in cross-platform like: UNIX and windows. It will generate path separator as per OS at runtime. os.sep is similar like File.separtor in java

Breathtaking answered 29/1, 2018 at 7:32 Comment(0)
R
2
TakeScreenShot screenshot=new TakeScreenShot();
screenshot.screenShot("screenshots//TestScreenshot//password.png");

it will work , please try.

Ruckus answered 20/6, 2019 at 11:2 Comment(0)
P
1

In Django(Python), you can take the screenshots of Django Admin on headless Google Chrome, Microsoft Edge and Firefox as shown below. *I use pytest-django and selenium and my answer explains how to do this on the headless browsers together:

<Google Chrome>

import pytest
from selenium import webdriver

def take_screenshot(driver, name):
    os.makedirs(os.path.join("screenshot", os.path.dirname(name)), exist_ok=True)
    driver.save_screenshot(os.path.join("screenshot", name))

def test_1(live_server):
    options = webdriver.ChromeOptions()
    options.add_argument("--headless=new")
    driver = webdriver.Chrome(options=options)
    driver.set_window_size(1024, 768)
    driver.get(("%s%s" % (live_server.url, "/admin/")))
    take_screenshot(driver, "admin/chrome.png")
    assert "Log in | Django site admin" in driver.title

<Microsoft Edge>

import pytest
from selenium import webdriver

def take_screenshot(driver, name):
    os.makedirs(os.path.join("screenshot", os.path.dirname(name)), exist_ok=True)
    driver.save_screenshot(os.path.join("screenshot", name))

def test_1(live_server):
    options = webdriver.EdgeOptions()
    options.add_argument("--headless=new")
    driver = webdriver.Edge(options=options)
    driver.set_window_size(1024, 768)
    driver.get(("%s%s" % (live_server.url, "/admin/")))
    take_screenshot(driver, "admin/edge.png")
    assert "Log in | Django site admin" in driver.title

<Firefox>

import pytest
from selenium import webdriver

def take_screenshot(driver, name):
    os.makedirs(os.path.join("screenshot", os.path.dirname(name)), exist_ok=True)
    driver.save_screenshot(os.path.join("screenshot", name))

def test_1(live_server):
    options = webdriver.FirefoxOptions()
    options.add_argument("-headless")
    driver = webdriver.Firefox(options=options)
    driver.set_window_size(1024, 768)
    driver.get(("%s%s" % (live_server.url, "/admin/")))
    take_screenshot(driver, "admin/firefox.png")
    assert "Log in | Django site admin" in driver.title
Plumbiferous answered 14/9, 2023 at 15:14 Comment(0)
R
0

Have a look on the below python script to take snap of FB homepage by using selenium package of Chrome web driver.

Script:

import selenium

from selenium import webdriver

import time

from time import sleep

chrome_browser = webdriver.Chrome()

chrome_browser.get('https://www.facebook.com/') # Enter to FB login page

sleep(5)

chrome_browser.save_screenshot('C:/Users/user/Desktop/demo.png') # To take FB homepage snap

chrome_browser.close() # To Close the driver connection

chrome_browser.quit() # To Close the browser
Roer answered 20/11, 2020 at 16:11 Comment(0)
B
0

It's quite simple, plz try this:

from selenium import webdriver

driver = webdriver.Chrome()

def take_screenshot(name):
    driver.get_screenshot_as_file(f"./screenshot/{name}.png")

#Or with datetime:
def take_screenshot_with_dt(name):       
    datetime.now()
    screenDatetime = datetime.now().strftime('%d-%m-%Y-%H-%M')
    driver.get_screenshot_as_file(f"./screenshot/{name}-{screenDatetime}.png")



take_screenshot("screenshotName")
take_screenshot_with_dt("screenshotNameDt")
Breve answered 24/3, 2022 at 19:51 Comment(0)
L
0

write this hook in conftest.py

@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
    pytest_html = item.config.pluginmanager.getplugin("html")
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, "extra", [])
    if report.when == "call":
        # always add url to report
        extra.append(pytest_html.extras.url(driver.current_url))
        xfail = hasattr(report, "wasxfail")
        if (report.skipped and xfail) or (report.failed and not xfail):
            report_directory = os.path.dirname(item.config.option.htmlpath)
            file_name = report.nodeid.replace("::", "_") + ".png"
            destination_file = os.path.join(report_directory, file_name)
            driver.save_screenshot(destination_file)
            if file_name:
                html = '<div><img src="%s" alt="screenshot" style="width:300px;height=200px"'\
                    'onclick="window.open(this.src)" align="right"/></div>'%file_name
            # only add additional html on failure
                extra.append(pytest_html.extras.html(html))
        report.extra = extra
Lette answered 30/5, 2022 at 6:51 Comment(0)
E
-2
WebDriver driver = new FirefoxDriver();
driver.get("http://www.google.com/");
File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(scrFile, new File("c:\\NewFolder\\screenshot1.jpg"));
Exultant answered 11/9, 2019 at 13:34 Comment(1)
Please provide some explanations to go along with your code.Thurman
G
-10

I understand you are looking for an answer in python, but here is how one would do it in ruby..

http://watirwebdriver.com/screenshots/

If that only works by saving in current directory only.. I would first assign the image to a variable and then save that variable to disk as a PNG file.

eg:

 image = b.screenshot.png

 File.open("testfile.png", "w") do |file|
  file.puts "#{image}"
 end

where b is the browser variable used by webdriver. i have the flexibility to provide an absolute or relative path in "File.open" so I can save the image anywhere.

Gossipry answered 12/10, 2012 at 6:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.