Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsUse Selenium WebDriver to open a page and call driver.save_screenshot('/absolute/path/screenshot.png'). The method captures the current browser window (the current browsing context) as a PNG and returns True when the file is saved. A complete script is:
from selenium import webdriver
driver = webdriver.Chrome()
try:
driver.get('https://www.example.com')
saved = driver.save_screenshot('/tmp/screenshot.png')
if not saved:
raise OSError('Selenium could not save the screenshot')
finally:
driver.quit()
Use a writable destination ending in .png, select the intended tab or window before capturing, and always quit the driver.
Install Selenium and prepare a writable path
Install Selenium in the Python environment that will run the script:
python -m pip install -U selenium
The documented API reference for Selenium 4.49.0 includes the methods used below. If you use an older Selenium release, check that your installed version exposes the same methods. Selenium can manage a compatible browser driver through its current setup mechanisms, but the browser itself must be installed on the machine.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11#1 Best Overall
Choose a destination
Create the output directory first when necessary and make sure the account running Python can write to it. A failed write is reported as an I/O failure; using an absolute path makes the result easier to find in scheduled jobs and CI.
from pathlib import Path
output = Path('/tmp/selenium-shot.png')
output.parent.mkdir(parents=True, exist_ok=True)
Capture the current browser window
save_screenshot() captures the current browsing context. Navigate first, wait for the page state your test needs, then save the PNG.
from pathlib import Path
from selenium import webdriver
url = 'https://www.example.com'
output = Path('/tmp/example.png')
output.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get(url)
if not driver.save_screenshot(str(output)):
raise OSError(f'Could not write screenshot to {output}')
print(f'Saved {output}')
finally:
driver.quit()
The return value is a Boolean. Treat False as a failure instead of letting a test continue with a missing image. The browser is closed in finally, including when navigation or file writing raises an exception.
Control the viewport before capture
A screenshot reflects the current window size. Set a deterministic viewport when image comparisons or documentation require consistent dimensions:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
driver.set_window_size(1440, 900)
driver.get('https://www.example.com')
driver.save_screenshot('/tmp/desktop.png')
Set the size before navigation when the page’s responsive layout is chosen during initial load. Selenium’s basic screenshot method captures the visible window, not an automatically stitched, full-page image.
Rank #2
Capture the selected tab or window
WebDriver commands apply to the active window handle. After opening another tab or window, switch to the handle containing the page you want:
handles = driver.window_handles
driver.switch_to.window(handles[-1])
driver.save_screenshot('/tmp/active-window.png')
Do not assume the last handle is always the desired one in a complex test; inspect titles or URLs and switch explicitly.
Save one web element instead of the whole page
Locate an element and call its screenshot() method. Selenium’s Python example uses an h1; any displayed element that can be located can be the target.
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
try:
driver.get('https://www.example.com')
heading = driver.find_element(By.TAG_NAME, 'h1')
if not heading.screenshot('/tmp/heading.png'):
raise OSError('Element screenshot was not saved')
finally:
driver.quit()
The element image is useful for a component regression test, a product-card catalog, or a focused bug report. A selector that matches nothing raises a locate error, so use a stable ID, data attribute, or other selector owned by the page rather than a fragile positional expression.
Keep the screenshot in memory
PNG bytes
Use get_screenshot_as_png() when the next step uploads, hashes, or processes binary data without creating an intermediate file.
from selenium import webdriver
driver = webdriver.Chrome()
try:
driver.get('https://www.example.com')
png_bytes = driver.get_screenshot_as_png()
with open('/tmp/from-bytes.png', 'wb') as image_file:
image_file.write(png_bytes)
finally:
driver.quit()
Base64 text
get_screenshot_as_base64() returns a base64 string, which is convenient for embedding in HTML or sending through a text-oriented API.
from selenium import webdriver
driver = webdriver.Chrome()
try:
driver.get('https://www.example.com')
encoded = driver.get_screenshot_as_base64()
data_uri = 'data:image/png;base64,' + encoded
print(data_uri[:80] + '...')
finally:
driver.quit()
Choose bytes for binary storage and base64 for a consumer that explicitly expects text. Both represent a PNG of the current browsing context.
Wait for the page you actually want to capture
driver.get() returns according to the browser’s normal navigation behavior, but application content can continue rendering afterward. Waiting for a meaningful condition avoids capturing a loading skeleton or an empty component.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
driver.get('https://www.example.com/dashboard')
WebDriverWait(driver, 20).until(
lambda d: d.find_element(By.CSS_SELECTOR, '[data-ready="true"]')
)
driver.save_screenshot('/tmp/dashboard-ready.png')
Use an explicit wait for a selector, a title, a URL change, or another observable state. A fixed sleep can work for a simple demonstration but is slower and less reliable when network speed varies. If the page lazy-loads images only after scrolling, perform the required scroll and wait for the images before saving.
Headless and automated runs
For servers without a display, add Chrome’s headless argument. Keep the same screenshot calls; only browser startup changes.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--window-size=1440,900')
driver = webdriver.Chrome(options=options)
try:
driver.get('https://www.example.com')
driver.save_screenshot('/tmp/headless.png')
finally:
driver.quit()
Headless and headed browsers can render slightly differently because of fonts, GPU settings, extensions, and available system packages. Pin the browser, driver, viewport, and fonts in visual-regression jobs when pixel consistency matters.
Common failures and fixes
The file is missing or save_screenshot() returns False
- Use a full path ending in
.png. - Create the parent directory before capture.
- Check write permissions for the user running Python, especially in containers and CI.
- Verify that another process is not locking or replacing the destination.
SessionNotCreatedException or the browser will not start
Install a supported browser, use a compatible Selenium setup, and inspect the driver startup error for version or sandbox details. In Linux containers, headless mode and the required browser libraries may be necessary.
NoSuchElementException for an element screenshot
The selector did not match at capture time. Confirm the URL, switch to the correct frame or window, wait for the element, and use a stable selector. If the element is inside an iframe, switch into that frame before locating it.
The image shows a blank page or a loading state
Capture only after a page-specific readiness condition. Check redirects, authentication, JavaScript errors, and network access. For content below the fold, scroll or trigger the page’s lazy-loading behavior before taking the shot.
The wrong tab is captured
Inspect driver.window_handles, switch with driver.switch_to.window(handle), and verify driver.current_url before saving.
Free tools Windows power users keep installed
One-click scans. No signup required.
Best Value
Only part of the page is visible
save_screenshot() is a viewport screenshot. Set a larger window for more visible content, or capture sections/elements separately. It is not the same as a full-page stitched capture.
Reliability, performance, and storage choices
- Reuse a session when appropriate: one browser session can capture several pages, reducing startup overhead. Quit it in a final cleanup block.
- Use deterministic waits: condition-based waits reduce flaky images and avoid an unnecessarily long fixed delay.
- Control output size: a larger viewport and dense page increase PNG size and memory use. Resize or compress after capture if your downstream system permits it.
- Protect sensitive images: screenshots can contain account data, tokens, or personal information. Store them with restricted permissions and remove temporary files.
- Make failures visible: check the Boolean return for file output and catch navigation, timeout, and selector exceptions so CI reports the actual cause.
Or skip the browser setup
ScreenshotNeo provides a single-request screenshot API when you do not need to manage Selenium, a browser binary, and a driver. It removes cookie banners, newsletter popups, and chat widgets before the capture. Bot checks, 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. Its MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
See the ScreenshotNeo API documentation for authentication and options. A GET request returns PNG, JPEG, WebP, or PDF depending on the parameters:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Every plan includes the feature set, including full-page and element capture, device and viewport controls, dark mode, custom CSS and JavaScript, waits, request blocking, cookies and headers, geolocation, PDFs, signed links, asynchronous jobs, bulk capture, caching, and a usage API. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Create a free ScreenshotNeo account.
Recommended Free Tools
When Selenium is the better choice
Selenium is appropriate when the screenshot is one step in an interactive test: you need to log in through a real browser, click controls, inspect DOM state, switch frames, or produce an in-memory image inside an existing Python test. An API is simpler when your input is primarily a URL and you want repeatable remote capture without maintaining browser infrastructure.
Frequently Asked Questions
Does Selenium save screenshots as JPEG or WebP?
The documented Python screenshot file methods produce PNG output. Convert the resulting image afterward if another format is required.
Can I capture a screenshot without writing a file?
Yes. Use get_screenshot_as_png() for PNG bytes or get_screenshot_as_base64() for a base64 string.
What does Selenium mean by the current browsing context?
It is the active WebDriver window or tab. Switch to the intended handle before calling a screenshot method.
Why should a script call driver.quit()?
It closes the browser session and releases its driver process and resources, including when cleanup runs from a finally block.
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.

