What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Create the destination first, join the filename with pathlib.Path, then pass the resulting PNG path to Selenium. This pattern creates missing parent folders, works when the folder already exists, and makes a failed write visible:
from pathlib import Path
screenshot_dir = Path("screenshots")
screenshot_dir.mkdir(parents=True, exist_ok=True)
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}")
The reliable folder-and-screenshot pattern
driver.save_screenshot() writes the current browser window as a PNG file. It does not create missing directories for you, so create the directory before calling it:
- Choose a destination with
Path. - Call
mkdir(parents=True, exist_ok=True). - Join the filename with the directory using the
/operator. - Call
driver.save_screenshot(str(path)). - Check the returned Boolean and raise an error when it is
False.
The Selenium API documents a full filename ending in .png. A false return indicates an I/O failure, so checking it prevents a test or job from continuing as though an artifact had been created.
A complete Python example
The following example assumes that driver is an already initialized Selenium WebDriver. Put the save operation after navigation and after any wait needed for the page state you want to record.
#1 Best Overall
- 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.
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
def save_page_screenshot(driver, relative_name="page.png"):
output_root = Path("artifacts")
output_root.mkdir(parents=True, exist_ok=True)
destination = output_root / relative_name
destination.parent.mkdir(parents=True, exist_ok=True)
if destination.suffix.lower() != ".png":
raise ValueError("Selenium save_screenshot expects a .png filename")
if not driver.save_screenshot(str(destination)):
raise OSError(f"Screenshot could not be written: {destination}")
return destination
options = Options()
# Add your normal browser options here, such as headless mode in CI.
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
path = save_page_screenshot(driver, "home/page.png")
print(f"Saved {path}")
finally:
driver.quit()
If artifacts is missing, it is created. The nested home directory is also created because the function creates the parent of the final path. Remove the nested-directory line when callers are allowed to supply only a filename.
Why each part matters
Path.mkdir(parents=True, exist_ok=True)
parents=True creates missing ancestors, not just the final directory. For example, it can create artifacts/2026/09/30 in one call. exist_ok=True makes repeated test runs safe when the directory is already present; without it, an existing directory can raise FileExistsError.
Joining paths instead of concatenating strings
screenshot_dir / "page.png" lets pathlib insert the platform’s separator and avoids errors such as missing or doubled slashes. Convert the final Path to str for broad WebDriver compatibility. Python path objects implement the filesystem path protocol, but the explicit conversion matches Selenium’s documented filename parameter.
Using a PNG extension
The ordinary Selenium screenshot method is specified as PNG output. Give it a filename ending in .png; changing the suffix to .jpg does not turn this API into a JPEG encoder.
Checking the return value
Selenium returns True when the write succeeds and False for an I/O error. The method may not raise an exception for every failed write, so the explicit check is important in CI and automated tests.
Relative paths, absolute paths, and predictable output
A relative path such as Path("screenshots") is resolved from the Python process’s current working directory, not necessarily from the directory containing your script. An IDE, test runner, Docker container, or CI job can choose a different working directory.
Rank #2
- 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.
Print the resolved location while diagnosing an unexpected destination:
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minutefrom pathlib import Path
folder = Path("screenshots")
print(folder.resolve())
When the artifact must always live under a known project directory, derive an absolute base explicitly:
project_root = Path(__file__).resolve().parent
screenshot_dir = project_root / "artifacts" / "screenshots"
screenshot_dir.mkdir(parents=True, exist_ok=True)
path = screenshot_dir / "page.png"
if not driver.save_screenshot(str(path)):
raise OSError(f"Could not save {path}")
In a test suite, a configurable output-root environment variable is often more practical than tying artifacts to the source file:
import os
from pathlib import Path
root = Path(os.environ.get("SCREENSHOT_DIR", "screenshots"))
root.mkdir(parents=True, exist_ok=True)
Preventing accidental overwrites
Saving repeatedly to page.png replaces the previous file. That is useful when you want the latest state, but not when each failure must be preserved. Add a test name, timestamp, or unique identifier to the filename:
from datetime import datetime, timezone
from pathlib import Path
folder = Path("screenshots")
folder.mkdir(parents=True, exist_ok=True)
stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
path = folder / f"checkout-{stamp}.png"
if not driver.save_screenshot(str(path)):
raise OSError(f"Could not save {path}")
For parallel workers, include the worker ID or a UUID so two processes do not select the same name. If deterministic filenames are required for a report, write each run into a separate run directory instead.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Choose the screenshot scope deliberately
The standard driver method captures the current browser window. It is not automatically a full, vertically stitched page.
Rank #3
- 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.
| Need | Selenium API | What it captures |
|---|---|---|
| Visible browser state | driver.save_screenshot(filename) |
The current window, written as PNG. |
| One component | element.screenshot(filename) |
The selected WebElement, written as PNG. |
| Entire document | Firefox-specific full-document screenshot methods | A browser-specific full-page capture; verify support for your browser and Selenium version. |
Element capture follows the same directory pattern:
from pathlib import Path
folder = Path("screenshots")
folder.mkdir(parents=True, exist_ok=True)
card = driver.find_element("css selector", ".product-card")
path = folder / "product-card.png"
if not card.screenshot(str(path)):
raise OSError(f"Could not save element screenshot to {path}")
Use an element screenshot when the requirement is a component, not a viewport. For a full-document image, do not assume that the ordinary method provides browser-independent behavior; use an API explicitly documented for the browser you run.
Timing and page state
A screenshot records the page at the instant the command runs. Navigate first, then wait for the content that must appear. A fixed sleep can be appropriate for a known animation, but a condition-based wait is usually less brittle. Capture after dismissing your own test fixtures, selecting the correct tab or frame, and scrolling to the state you intend to document.
Free tools Windows power users keep installed
One-click scans. No signup required.
If lazy-loaded images are absent, scroll or wait for the application’s loading condition before saving. Selenium’s file-writing step cannot repair a page that was captured too early.
Troubleshooting checklist
“No such file or directory”
The parent folder was not created, or one of its ancestors is missing. Call mkdir(parents=True, exist_ok=True) on the destination directory before saving. If the filename contains subdirectories, create path.parent, not only the top-level folder.
The method returns False
Treat this as an I/O failure. Print the absolute path, verify that the parent exists, check write permissions, confirm that the path is not a directory, and ensure the process has not run out of disk space. Raising immediately keeps a broken artifact from being reported as successful.
Rank #4
- 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 file is in the wrong folder
Resolve the relative path and inspect the process working directory. Configure an absolute output root or change the runner’s working directory deliberately rather than guessing where Selenium wrote the file.
Recommended Free Tools
Earlier screenshots disappeared
You reused the same filename. Add a timestamp, test identifier, worker identifier, or run-specific directory.
The image shows only part of the page
That is the expected scope of the ordinary current-window method. Use element.screenshot() for a component, or a documented full-document method supported by your browser.
Permissions work locally but fail in CI
CI may run as a different user or inside a read-only workspace. Select a writable artifact directory, create it during setup, and publish that directory using your CI system’s artifact mechanism.
The screenshot is blank or stale
Check navigation completion, waits, frame and window selection, authentication state, and any overlay covering the page. Capture only after the DOM and visual state required by the test are ready.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Performance, reliability, and maintenance
- Create one run directory and reuse it instead of repeatedly probing for directory existence in every helper.
- Keep screenshot names deterministic when a report needs one known path; use unique names only where historical artifacts matter.
- Close the driver in a
finallyblock so browser processes do not accumulate after a failed save. - Do not treat a successful file write as proof that the page was correct; validate the page state separately.
- Retain only the artifacts your debugging and compliance policy requires, especially when screenshots contain personal or secret data.
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 operate Selenium for a URL capture. Before 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 disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and whether it was billed.
Read the parameter details in the ScreenshotNeo documentation. Replace YOUR_API_KEY and the target URL as needed.
Best Value
- [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.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
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}`);
Options relevant to automated captures
ScreenshotNeo supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or a custom viewport, retina scale, PDF paper size, margins, landscape mode and page ranges, HTML/CSS-to-image rendering, custom CSS and JavaScript, pre-capture clicks, hidden selectors, waits for a selector, delay or network idle, ad/tracker/request/resource blocking, custom headers, cookies, user agent and Authorization, timezone and geolocation, transparent backgrounds, image resizing, selectable cache TTL, signed links for public image tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and familiar parameter names that ease migration from other screenshot APIs. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
| Plan | Included screenshots | Price |
|---|---|---|
| Free | 1,000 per month | $0, no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing provides two months free, and every feature is available on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots each month without adding a card.
Frequently Asked Questions
Can I pass a pathlib.Path directly to Selenium?
Python path objects support the filesystem path protocol, but converting the final path with str(…) is the clearest choice for compatibility with different WebDriver implementations.
Should screenshots be committed to source control?
Usually no. Store them in a CI artifact location or an ignored output directory, unless a screenshot is intentionally a versioned visual fixture.
How should I handle sensitive screenshots?
Use test accounts and masked data where possible, restrict artifact permissions, define retention limits, and remove files that contain credentials, tokens, or personal information.
Quick Recap
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.

