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.

Use pathlib.Path.mkdir(parents=True, exist_ok=True) to create the destination folder, join the filename with that folder, and pass the resulting path to Selenium’s driver.save_screenshot(). Check the method’s Boolean result so an I/O failure cannot pass silently.

Complete Python example

This script creates a screenshots directory if necessary, opens a page, saves the current browser window as a PNG, and raises an error if Selenium reports that the file could not be written.

from pathlib import Path
from selenium import webdriver

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

# Configure the driver that your project uses.
driver = webdriver.Chrome()

try:
    driver.get("https://example.com")

    screenshot_path = screenshot_dir / "page.png"
    saved = driver.save_screenshot(str(screenshot_path))

    if not saved:
        raise OSError(f"Could not save screenshot to {screenshot_path}")
finally:
    driver.quit()

Run the program from your project directory. The relative path screenshots/page.png is resolved against the Python process’s current working directory, not necessarily the directory containing the script.

Why this pattern works

Create the directory before saving

Path.mkdir(parents=True, exist_ok=True) handles both a first run and later runs. parents=True creates missing ancestors, so a path such as artifacts/ui/screenshots works even when none of those directories exists. exist_ok=True prevents an exception when the target directory is already present.

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.
#1 Best Overall
Sale
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
  • Easily store and access 2TB to content on the go with the Seagate Portable Drive, a USB external hard drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

Join paths instead of concatenating strings

The expression screenshot_dir / "page.png" uses pathlib‘s path-aware joining. It avoids manually choosing slash or backslash separators and makes it easy to replace the output directory or filename later.

Use a PNG filename

Selenium’s save_screenshot(filename) API writes the current browser window as a PNG and expects a full filename ending in .png. Converting the Path with str() is explicit and compatible with WebDriver implementations that document a string filename.

Check the return value

The method returns a Boolean. A false result indicates an I/O error. Treat it as a failed test artifact and report the path, rather than continuing as though the screenshot exists.

Choose an output location deliberately

Relative project folder

from pathlib import Path

output_dir = Path("test-output") / "screenshots"
output_dir.mkdir(parents=True, exist_ok=True)
path = output_dir / "login.png"

This is convenient for local development and CI jobs that collect a known workspace folder. Remember that the process working directory can differ between an IDE, a shell, and a CI runner.

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

Folder beside the Python file

from pathlib import Path

project_root = Path(__file__).resolve().parent
output_dir = project_root / "screenshots"
output_dir.mkdir(parents=True, exist_ok=True)
path = output_dir / "page.png"

Using __file__ makes the location independent of where the command was launched. In packaged applications, use the application’s configured writable directory instead; an installation directory may be read-only.

Rank #2
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
  • Easily store and access 5TB of content on the go with the Seagate portable drive, a USB external hard Drive
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

Absolute path supplied by configuration

import os
from pathlib import Path

output_dir = Path(os.environ.get("SCREENSHOT_DIR", "screenshots")).expanduser()
output_dir.mkdir(parents=True, exist_ok=True)
path = output_dir / "page.png"

Configuration is useful when a CI system mounts an artifact volume or when different operating systems use different output roots.

Preserve every capture instead of overwriting

Selenium writes to the filename you provide. Reusing page.png replaces the previous capture. Add a timestamp, test name, or unique identifier when each result matters.

from datetime import datetime, timezone
from pathlib import Path

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

stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = output_dir / f"checkout-{stamp}.png"
if not driver.save_screenshot(str(path)):
    raise OSError(f"Could not save screenshot to {path}")

For parallel tests, include a worker or test identifier as well as the timestamp. A timestamp alone can still collide when multiple processes start in the same second.

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

What Selenium actually captures

Current browser window

driver.save_screenshot() captures the current window at the moment the call runs. It does not automatically capture every pixel below the viewport. Wait until navigation and relevant asynchronous content have completed before calling it.

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

wait = WebDriverWait(driver, 20)
driver.get("https://example.com/dashboard")
wait.until(lambda d: d.find_element(By.CSS_SELECTOR, "main.loaded"))

path = Path("screenshots") / "dashboard.png"
path.parent.mkdir(parents=True, exist_ok=True)
if not driver.save_screenshot(str(path)):
    raise OSError("Screenshot save failed")

A single element

When the requirement is a component rather than the viewport, call screenshot() on the element.

Rank #3
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
  • Easily store and access 1TB to content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop. Reformatting may be required for Mac
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.
element = driver.find_element(By.CSS_SELECTOR, "#invoice-summary")
element_path = Path("screenshots") / "invoice-summary.png"
element_path.parent.mkdir(parents=True, exist_ok=True)

if not element.screenshot(str(element_path)):
    raise OSError(f"Could not save element screenshot to {element_path}")

This API also writes PNG output and returns a Boolean. The element must be present and visible enough for the browser driver to capture it.

Full-document images

Full-page behavior is separate from the ordinary current-window call. Firefox’s Python WebDriver API exposes full-document screenshot methods; support and behavior differ by browser and driver. If portability across Chrome, Edge, and Firefox is required, verify the specific driver APIs rather than assuming that save_screenshot() means full document.

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

Reusable helper function

Centralize directory creation, naming, and error handling so every test follows the same policy.

from pathlib import Path
from typing import Union

PathLike = Union[str, Path]

def save_window_screenshot(driver, directory: PathLike, filename: str) -> Path:
    output_dir = Path(directory)
    output_dir.mkdir(parents=True, exist_ok=True)

    if not filename.lower().endswith(".png"):
        raise ValueError("Selenium screenshots must use a .png filename")

    destination = output_dir / filename
    if not driver.save_screenshot(str(destination)):
        raise OSError(f"Could not save screenshot to {destination}")
    return destination

# Example:
path = save_window_screenshot(driver, "artifacts/screenshots", "home.png")
print(f"Saved {path.resolve()}")

Keep filenames controlled by your application. If a test name can contain slashes, colons, or other platform-specific characters, sanitize it before using it as a filename.

Troubleshooting

“No such file or directory”

The parent directory was not created, or an ancestor is missing. Build the destination with Path and call destination.parent.mkdir(parents=True, exist_ok=True) before saving.

Rank #4
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
  • Easily store and access 4TB of content on the go with the Seagate Portable Drive, a USB external hard drive.Specific uses: Personal
  • Designed to work with Windows or Mac computers, this external hard drive makes backup a snap just drag and drop
  • To get set up, connect the portable hard drive to a computer for automatic recognition no software required
  • This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable
  • The available storage capacity may vary.

The method returns False

This is Selenium’s documented I/O-failure result. Print Path.resolve() to confirm the actual target, check that the parent exists, verify write permission, and ensure another process has not locked or replaced the path. In a container or CI job, confirm that the destination volume is mounted and writable.

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

FileExistsError from mkdir

Use exist_ok=True when the path is expected to be an existing directory. If the target path exists but is a file, fix the configuration or choose another directory; exist_ok=True cannot turn a file into a directory.

The file is in an unexpected folder

Relative paths follow the process working directory. Log Path.cwd(), use an absolute configured root, or derive the path from Path(__file__).resolve().parent.

The image shows the wrong state

Capture only after navigation, animations, lazy content, and required elements are ready. Use an explicit wait for a meaningful selector instead of a fixed sleep whenever possible. For a component, use WebElement.screenshot(); for a document-length image, use a browser-specific full-document method that your target browser supports.

Old files disappear

The same filename is being reused. Add a test identifier, UTC timestamp, or unique ID, and have your CI artifact-retention policy clean up old files separately.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
UnionSine 500GB Ultra Slim Portable External Hard Drive HDD-USB 3.0
  • [Upgraded Version] - This external hard drive features a mirrored logo stripe combined with a striped anti-slip design, and the rounded corners of the casing make it easier to grip. The stripes also have a heat dissipation function, ensuring stable and fast data transfer.
  • 【Ultra-thin and quiet】 - The motherboard adopts JMicron 578 noise-free solution, giving you a quiet working environment. Lightweight and portable size designed to fit in your pocket for easy portability.
  • 【Ultra-Fast Data Transfers】 - Pairing this external hard drive with JMicron 578 solution USB 3.0 and USB 2.0 interfaces enables blazing-fast data transfer. It boasts theoretical read speeds of up to 125MB/s and write speeds of up to 103MB/s.
  • 【Plug and Play】 - With no software to install, just plug it in and the drive is ready to use.The hard disk chip is wrapped with an aluminum anti-interference layer to increase heat dissipation and protect data.
  • 【What You Get】 - 1 x Portable Hard Drive, 1 x USB 3.0 Cable, 1 x User Manual, Gift-type shell packaging ,Three-year manufacturer's warranty and free technical support services.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Operational considerations

  • Permissions: choose a writable workspace, especially in containers, services, and hosted CI runners.
  • Cleanup: decide whether screenshots are debugging artifacts, permanent test evidence, or temporary files. Apply retention rules outside the save function.
  • Failure handling: preserve the original test exception while recording screenshot-save failures, so an artifact problem does not hide the actual browser failure.
  • Concurrency: give each worker its own subdirectory or collision-resistant filename.
  • Verification: check the Boolean result and, where your workflow needs stronger guarantees, confirm that the resulting file exists and has a nonzero size.

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 need to install or manage a Selenium browser for a straightforward URL capture. Before the capture, it accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and whether the request was billed. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

See the complete parameter reference in the ScreenshotNeo documentation. This cURL request saves a WebP response:

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

The equivalent Python request is:

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)

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 failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, PDF paper settings and page ranges, custom CSS and JavaScript, pre-capture clicks, selector hiding, waits for selectors, delays or network idle, request and resource blocking, headers, cookies, user agents, Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API, an OpenAPI specification, and compatibility with parameter names used by other screenshot APIs.

Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Growth is $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is included on every plan. Create a free ScreenshotNeo account to start with the 1,000 monthly screenshots.

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

Frequently Asked Questions

Can I pass a pathlib.Path directly to Selenium?

Python paths implement the filesystem path protocol, but converting the path with str() matches Selenium’s documented filename parameter and is explicit across WebDriver implementations.

Does save_screenshot capture the whole page?

The ordinary driver method captures the current window. Use an element screenshot for one component or a browser-specific full-document API when you need content beyond the viewport.

Why should I use exist_ok=True?

It makes repeated test runs safe when the destination directory already exists. It does not fix a path whose target is an existing file.

Quick Recap

SaleBestseller No. 1
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
Seagate 2TB Portable Hard Drive | USB 3.0 (STGX2000400)
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$129.99
Bestseller No. 2
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
Seagate Portable 5TB External Hard Drive HDD – USB 3.0 for PC, Mac, PS4, & Xbox - 1-Year Rescue Service (STGX5000400), Black
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$180.19
Bestseller No. 3
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
Seagate Portable 1TB External Hard Drive HDD – USB 3.0 for PC, Mac, PlayStation, & Xbox, 1-Year Rescue Service (STGX1000400) , Black
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$119.80
Bestseller No. 4
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
Seagate Portable 4TB External Hard Drive HDD – USB 3.0, 1-Year Rescue
This USB drive provides plug and play simplicity with the included 18 inch USB 3.0 cable; The available storage capacity may vary.
$189.90

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.