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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

The shortest reliable solution is driver.save_screenshot("screenshots/page.png"). It captures the current browser window and writes a PNG file. Create the destination directory first, use a writable path ending in .png, and check the returned Boolean when your script must detect write failures.

Save the current Selenium window as a PNG

This complete example works with Selenium’s Python bindings and Chrome WebDriver. The context manager closes the browser even if a later operation raises an exception.

from pathlib import Path
from selenium import webdriver

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

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    ok = driver.save_screenshot(str(out / "example.png"))
    if not ok:
        raise OSError("Selenium could not write the screenshot")

After a successful run, screenshots/example.png contains the screenshot of the browser’s current window. The call is synchronous: Selenium asks the driver for PNG data, writes it to the path, and returns True when that succeeds.

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.

Prerequisites

  • Python and the Selenium package installed in the environment running the script.
  • A browser (Chrome in the example) and a compatible WebDriver setup.
  • Write permission for the destination directory.

Navigate to the page before capturing. If the page loads content asynchronously, wait for the relevant element or condition first; a screenshot records the state that exists at the instant of the call.

save_screenshot versus get_screenshot_as_file

For Python, these two methods have the same file-oriented behavior. save_screenshot(filename) is the concise, commonly used spelling; get_screenshot_as_file(filename) is its equivalent API. Selenium’s implementation delegates save_screenshot to get_screenshot_as_file.

Method Capture scope Output Success/failure behavior
driver.save_screenshot(path) Current browser window PNG file at path Returns True; returns False when an operating-system write error occurs
driver.get_screenshot_as_file(path) Current browser window PNG file at path Same file behavior and Boolean result
driver.get_screenshot_as_png() Current browser window PNG bytes in memory Lets surrounding code handle exceptions and choose when or where to write
element.screenshot(path) One WebElement PNG file Element screenshot operation; failures surface through the WebDriver call
element.screenshot_as_png One WebElement PNG bytes in memory Useful for processing or uploading an element image

Neither file method converts another format to PNG. If the filename does not end in .png, Selenium warns rather than silently changing the extension, so use an explicit PNG suffix.

Choose a safe filename and handle failures

Use pathlib instead of string concatenation

from pathlib import Path

path = Path("artifacts") / "checkout-home.png"
path.parent.mkdir(parents=True, exist_ok=True)
if not driver.save_screenshot(str(path)):
    raise OSError(f"Could not write {path}")

Path produces the correct separator on Windows, macOS and Linux. Use an absolute path when a test runner’s working directory is uncertain:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
path = Path.cwd() / "artifacts" / "checkout-home.png"

Generate unique names for repeated captures

from datetime import datetime, timezone

stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = Path("screenshots") / f"home-{stamp}.png"
path.parent.mkdir(exist_ok=True)
if not driver.save_screenshot(str(path)):
    raise OSError("Screenshot write failed")

Do not let untrusted URL text become a filename. Sanitize user-controlled values or map them to a fixed identifier before creating a path.

Save PNG bytes in memory

Use get_screenshot_as_png() when you need to inspect, transform, upload or otherwise process the image before deciding where to store it.

from pathlib import Path
from selenium import webdriver

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    png_bytes = driver.get_screenshot_as_png()
    Path("screenshots").mkdir(exist_ok=True)
    Path("screenshots/example.png").write_bytes(png_bytes)

The returned value is binary PNG data, not a base64 string. You can pass it directly to an image library, object-storage client or HTTP upload routine. Writing with Path.write_bytes preserves the binary content.

Capture only one element

When a full viewport image contains irrelevant interface chrome, locate the element and use the WebElement screenshot API.

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.
from pathlib import Path
from selenium import webdriver

out = Path("screenshots")
out.mkdir(exist_ok=True)

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    button = driver.find_element("css selector", "button.submit")
    button.screenshot(str(out / "submit-button.png"))

For in-memory processing, use button.screenshot_as_png:

element_png = button.screenshot_as_png
Path("screenshots/submit-button.png").write_bytes(element_png)

Element capture is distinct from viewport capture: the selector must resolve to an element, and the element must be present and capturable in the current page state.

Wait for the page before capturing

A navigation call can return before JavaScript-rendered content is ready. Wait for a specific condition rather than adding an arbitrary long sleep.

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

with webdriver.Chrome() as driver:
    driver.get("https://example.com")
    WebDriverWait(driver, 20).until(
        EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
    )
    path = Path("screenshots/ready.png")
    path.parent.mkdir(exist_ok=True)
    if not driver.save_screenshot(str(path)):
        raise OSError("Screenshot write failed")

For an element screenshot, wait for that exact element. For dynamic images, wait until the image has loaded or the page reports the application state you need; otherwise the PNG can legitimately show placeholders.

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

Full-page screenshots: a browser-specific distinction

save_screenshot captures the current window, not a guaranteed full document. Full-page capture is a separate capability. Firefox’s WebDriver API documents get_full_page_screenshot_as_file(path) and save_full_page_screenshot(path) for full-document PNG screenshots.

from pathlib import Path
from selenium import webdriver

out = Path("screenshots")
out.mkdir(exist_ok=True)

with webdriver.Firefox() as driver:
    driver.get("https://example.com/long-page")
    driver.save_full_page_screenshot(str(out / "long-page.png"))

These dedicated methods are Firefox-specific API options in the cited Selenium documentation; do not treat them as a universal cross-browser guarantee. If your test suite must run across browsers, define the required capture scope explicitly and verify the behavior of each browser/driver combination instead of assuming that viewport capture includes content below the fold.

Common errors and fixes

The file is missing or the method returns False

  • Create the parent directory with mkdir(parents=True, exist_ok=True).
  • Use a path the test process can write to; containerized and CI users should check mounted directories and permissions.
  • Pass a full path ending in .png.
  • Check the Boolean result and raise an error immediately so a test cannot report success with no artifact.

The screenshot is from the wrong page or state

  • Call driver.get with the intended URL in the same browser session.
  • Wait for a page-specific element or condition before capturing.
  • Ensure a prior test has not left a modal, frame or tab active. Switch to the intended window or frame before taking the shot.

An element screenshot raises an element error

  • Verify the CSS selector and wait for the element to exist and be visible.
  • Re-find the element after a page re-render; a previously stored WebElement can become stale.
  • Scroll or otherwise bring the target into a capturable state when the browser/driver requires it.

The image is not full page

That is expected from save_screenshot: it is a current-window capture. Use Firefox’s documented full-page method where appropriate, or adopt a browser-specific full-page strategy and test its output on your supported drivers.

The PNG looks incomplete

Capture timing matters. Wait for the application’s content, fonts and images rather than assuming that the first successful navigation response means visual rendering is complete.

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

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF, so you do not have to install Selenium, a browser or a driver for a URL capture. The API accepts 63 options, including full-page capture with lazy images loaded, element capture by CSS selector, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, waits, click actions, hidden selectors, request blocking, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous webhooks and bulk capture of up to 100 URLs per call.

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)

See the ScreenshotNeo API documentation for the available parameters. The example requests the service’s default image response; choose the documented output option when you need PNG specifically.

cURL

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

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}`);

ScreenshotNeo accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Performance, reliability and cost decisions

  • Local Selenium: best when your test already owns a browser session, authentication state or DOM interaction. It carries browser and driver startup, memory and maintenance costs.
  • File versus bytes: direct file saving is simplest; bytes are better when you need image analysis, transformation or upload without an intermediate file.
  • Viewport versus element: viewport shots document the visible test state; element shots produce smaller, focused artifacts.
  • Full page: treat it as a browser capability, not an automatic property of every screenshot method.
  • Remote API: useful for URL-based captures, automation outside your test runner and AI-agent workflows. Account for network latency, authentication and the service’s plan limits.

A practical decision checklist

  1. Need the visible browser window? Use save_screenshot("name.png").
  2. Need to inspect or upload before writing? Use get_screenshot_as_png().
  3. Need one control, card or component? Use element.screenshot() or screenshot_as_png.
  4. Need the whole document? Use a documented browser-specific full-page API and validate cross-browser behavior.
  5. Need a URL screenshot without browser installation, with consent cleanup or MCP access? Use ScreenshotNeo and review its API options.

Frequently Asked Questions

Does Selenium save screenshots as PNG automatically?

Yes. The standard window and element screenshot file methods write PNG output; use a filename ending in .png.

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

Can I save a screenshot without creating a temporary file?

Yes. Call get_screenshot_as_png() or an element’s screenshot_as_png and process the returned bytes directly.

Why did my script create a warning about the extension?

Selenium expects a .png filename and warns when the supplied path does not end with that suffix; it does not silently convert the file.

Is save_screenshot a full-page screenshot?

No. It captures the current window. Full-document capture is a separate, browser-specific capability.

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.