What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The shortest working Selenium screenshot is driver.save_screenshot("page.png"). Open a WebDriver session, navigate to the target URL, wait for any content rendered after the initial load, save a PNG, check the Boolean result, and always call driver.quit(). The complete Python example below creates its output directory and cleans up the browser even when navigation or saving fails.

Minimal Python Selenium screenshot

Install Selenium in the Python environment used by your project, ensure a compatible Chrome browser and driver setup is available, then run this script:

from pathlib import Path
from selenium import webdriver

output = Path("screenshots")
output.mkdir(parents=True, exist_ok=True)

driver = webdriver.Chrome()
try:
    driver.get("https://example.com")
    saved = driver.save_screenshot(str(output / "page.png"))
    if not saved:
        raise OSError("Selenium could not save the screenshot")
finally:
    driver.quit()

save_screenshot captures the current browser window (the current browsing context) and writes a PNG file. Selenium returns True when the write succeeds and False for an I/O failure, so checking the result is useful in automated jobs. Use a filename ending in .png; a full path avoids ambiguity about the process’s working directory.

What each part of the script does

Create a destination that exists

Path("screenshots").mkdir(...) creates the folder and does nothing if it is already present. Without this step, the browser may be ready while the operating system rejects the file write because the directory is missing.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Start and stop WebDriver safely

The try/finally block guarantees that quit() runs after a successful capture, navigation exception, or save error. Quitting closes the browser and shuts down the driver process; omitting it can leave orphaned browser processes in CI or a long-running test suite.

Navigate before capturing

driver.get(url) navigates to the requested page and waits for the page’s load event. That does not mean every image, API response, chart, or client-rendered component is finished. Add an explicit wait when the visual state you need appears later.

Wait for dynamic content before the shot

For pages that render asynchronously, wait for a reliable condition rather than adding an arbitrary long sleep. For example, wait until a results container is present and visible:

from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

output = Path("screenshots")
output.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
    driver.get("https://example.com/dashboard")
    WebDriverWait(driver, 20).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main .results"))
    )
    if not driver.save_screenshot(str(output / "dashboard.png")):
        raise OSError("Screenshot write failed")
finally:
    driver.quit()

Choose a selector that represents the completed state, not a transient loading element. If there is no dependable selector, a bounded delay can be a fallback, but it is slower and more fragile than a condition wait.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose the capture scope

Current window

Use the driver method when you need what the active browser window displays:

driver.save_screenshot("page.png")

This is the general WebDriver operation documented for a current-window PNG. It captures the viewport as configured for the session; it is not automatically an image of every pixel in a long, scrollable document.

One element

Locate a component and call its screenshot method when the output should contain only that element:

from selenium.webdriver.common.by import By

element = driver.find_element(By.CSS_SELECTOR, "article.card")
element.screenshot("card.png")

Element screenshots are useful for regression tests, product previews, and isolating a widget from the surrounding page. The element must exist in the current browsing context, and it may need to be scrolled into view or made visible before capture.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Full document in Firefox

The Python Firefox API exposes save_full_page_screenshot:

from selenium import webdriver

driver = webdriver.Firefox()
try:
    driver.get("https://example.com/article")
    driver.save_full_page_screenshot("article-full.png")
finally:
    driver.quit()

Treat this as a Firefox-specific capability, not a portable replacement for save_screenshot across every browser driver. If your test matrix includes Chrome, Edge, or another driver, verify that browser’s documented full-page support or use a scrolling/assembly strategy designed for it.

Keep the screenshot in memory

You do not have to write an image immediately. Python exposes two alternatives:

  • driver.get_screenshot_as_png() returns PNG bytes, suitable for uploading to object storage, attaching to a test report, or processing with an image library.
  • driver.get_screenshot_as_base64() returns a Base64 string, which can be embedded in HTML or sent through a text-oriented interface.
png_bytes = driver.get_screenshot_as_png()
with open("page.png", "wb") as image_file:
    image_file.write(png_bytes)

base64_image = driver.get_screenshot_as_base64()

The file method is simplest when a local artifact is all you need. Bytes avoid a second read when another program step already accepts binary data; Base64 is convenient for HTML or JSON but increases the data size compared with raw PNG bytes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Browser size, device emulation, and visual consistency

A screenshot reflects the session’s viewport, device scale, fonts, zoom, color scheme, and loaded resources. Set the window size before navigation when tests must be repeatable:

driver.set_window_size(1440, 900)
driver.get("https://example.com")
driver.save_screenshot("desktop.png")

Use a separate driver configuration for mobile-sized viewports rather than resizing after the page has already chosen responsive breakpoints. For visual comparisons, keep browser version, operating system fonts, zoom level, and animation state consistent. If a page has a cookie dialog, chat launcher, or other overlay, close or hide it in the test setup before saving; Selenium captures whatever is visible.

Other Selenium language bindings

Selenium provides official examples for Java, Python, C#, Ruby, and JavaScript. The names differ by binding, but the sequence is the same: create a driver, navigate, capture the current context or element, persist the returned data, and dispose of the driver.

  • Java: cast the driver to TakesScreenshot, call getScreenshotAs(OutputType.FILE), and copy the resulting file to the desired destination.
  • Ruby: use the binding’s save_screenshot method.
  • JavaScript: call takeScreenshot(); the returned Base64 data can be decoded and written to a file.
  • C#: use the binding’s screenshot interface and save the returned image object according to the .NET API.

Check the API for your language’s return type: some bindings return a file or image object, while JavaScript returns encoded data. Do not treat a successful method call as proof that the bytes were written unless your code verifies the destination.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Common failures and precise fixes

The file is not created

  • Confirm the parent directory exists and the process has write permission.
  • Use a writable absolute path while diagnosing a CI failure.
  • Check the Boolean returned by save_screenshot and raise an error when it is False.
  • Use a .png filename for the Python file-saving method.

The screenshot is blank or incomplete

  • Wait for a visible, page-specific element after get().
  • Increase the explicit wait timeout only when the page’s real loading time requires it.
  • Check that the intended tab or window is selected; Selenium captures the current browsing context.
  • For lazy-loaded content, scroll or trigger the page’s loading behavior before capture, then wait for the content to appear.

A cookie banner or modal covers the page

Interact with the banner or modal before the screenshot, or hide the specific element with test-only JavaScript when that is acceptable for your visual test. Avoid globally hiding overlays if their appearance is itself what you are testing.

The browser never starts

Check that the browser is installed, the driver/browser versions are compatible, and the execution environment permits launching a graphical or headless session. In a server environment, configure the browser for the environment and inspect the original driver exception rather than masking it with a generic screenshot error.

Full-page output differs by browser

The general driver method is a current-window capture. Full-document methods are browser-specific, so test the exact browser and driver combination used in production. If portability matters more than a single native method, design a browser-neutral scrolling and stitching process and validate it against fixed visual fixtures.

Reliability and performance practices

  • Capture only after a meaningful condition: this reduces flaky artifacts caused by unfinished client rendering.
  • Reuse drivers carefully: a persistent session avoids startup cost, but reset cookies, storage, tabs, and viewport state between unrelated captures.
  • Use deterministic filenames: include a test name or timestamp while preventing concurrent workers from overwriting one another.
  • Preserve failures: take a screenshot in an exception handler, then re-raise the original test error so the artifact explains the failure without hiding it.
  • Limit oversized artifacts: choose an appropriate viewport and retention policy, especially when every test iteration uploads a PNG.
  • Run headless only when appropriate: headless mode is convenient for CI, but compare it with headed runs if fonts, GPU rendering, or layout is part of the acceptance criterion.

A useful failure-capture pattern is to save the current state in an exception path and still execute quit() in finally. That gives the test report evidence of the rendered page while preserving normal resource cleanup.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

If you need a screenshot service rather than a locally managed WebDriver, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers.

For a direct image request, see the ScreenshotNeo documentation:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

The same request from Python:

import requests
r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

And Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper and page-range controls, custom CSS and JavaScript, clicks, selector or network-idle waits, ad/tracker/request blocking, headers, cookies, user agents, Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable cache TTLs, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

It includes an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Every feature is on every plan: 1,000 screenshots per month are free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try the one-call approach.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

FAQ

What file type does Selenium’s Python save method create?

save_screenshot writes a PNG file and expects a filename ending in .png.

Can Selenium capture an element instead of the whole viewport?

Yes. Locate the element and call element.screenshot("element.png").

Is Selenium’s full-page screenshot method universal?

No. The documented Python save_full_page_screenshot method is a Firefox API; the general driver method captures the current window.

How can I send a screenshot without creating a file?

Use get_screenshot_as_png() for PNG bytes or get_screenshot_as_base64() for a Base64 string.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Does Selenium wait for JavaScript before taking a screenshot?

It waits for the navigation load event, but client-rendered content may arrive later. Wait for a page-specific element or state before saving.

Why should I check the return value of save_screenshot?

The Python method returns False when an I/O error prevents the file write; checking it lets an automated job fail clearly.

What should happen if navigation raises an exception?

Keep the driver in a try/finally block so quit() closes the browser and driver process even when navigation or capture fails.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.