user1152578
user1152578

Reputation: 815

Webdriver Screenshot in Python

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?

Upvotes: 73

Views: 149074

Answers (15)

unutbu
unutbu

Reputation: 879481

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')

Upvotes: 92

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

Upvotes: 1

Michael Tsioni
Michael Tsioni

Reputation: 11

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

Upvotes: 0

Fernando Nogueira
Fernando Nogueira

Reputation: 1566

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")

Upvotes: 0

Praveen Kumar C
Praveen Kumar C

Reputation: 439

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

Upvotes: 0

Dharit Mehta
Dharit Mehta

Reputation: 25

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"));

Upvotes: -2

suriya kanagaraj
suriya kanagaraj

Reputation: 29

TakeScreenShot screenshot=new TakeScreenShot();
screenshot.screenShot("screenshots//TestScreenshot//password.png");

it will work , please try.

Upvotes: 2

Ger Mc
Ger Mc

Reputation: 640

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'))

Upvotes: 7

gabriel de la cruz
gabriel de la cruz

Reputation: 61

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

Upvotes: 6

Shubham Jain
Shubham Jain

Reputation: 17553

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

Upvotes: 3

Shaik
Shaik

Reputation: 399

driver.save_screenshot("path to save \\screen.jpeg")

Upvotes: 7

Vladimir Kolenov
Vladimir Kolenov

Reputation: 438

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'

Upvotes: 5

Ran Adler
Ran Adler

Reputation: 3711

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()

Upvotes: 35

Kv.senthilkumar
Kv.senthilkumar

Reputation: 946

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')

Upvotes: 11

sambehera
sambehera

Reputation: 968

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.

Upvotes: -10

Related Questions