Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated 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 matchSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use driver.save_screenshot() inside the loop, but make the workflow reliable by creating the output directory first, waiting for the exact page state you need, generating a different .png path for every iteration, and checking Selenium’s Boolean result. The example below works with Selenium’s Python API and avoids the most common causes of overwritten, blank, or misleading captures.
A reliable loop, end to end
This script navigates to each URL, waits for a meaningful element, saves an indexed PNG, and raises an error if Selenium reports an I/O failure. The generic body wait is only a baseline; replace it with an application-specific condition whenever possible.
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
urls = [
"https://example.com/",
"https://www.selenium.dev/",
]
output_dir = Path("screenshots")
output_dir.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 15)
try:
for index, url in enumerate(urls, start=1):
driver.get(url)
# Replace this with the element or state that defines readiness.
wait.until(EC.presence_of_element_located((By.TAG_NAME, "body")))
path = output_dir / f"page_{index:03}.png"
if not driver.save_screenshot(str(path)):
raise OSError(f"Selenium could not save screenshot: {path}")
print(f"Saved {path}")
finally:
driver.quit()
Selenium documents save_screenshot(filename) as saving the current window to a PNG file. It returns True unless an I/O error occurs, in which case it returns False (Selenium Python WebDriver API). The filename should end in .png and resolve to a path writable by the process.
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 →Why each part matters
Create the directory before navigation
Selenium accepts a filename; it does not create missing parent folders for you. Path.mkdir(parents=True, exist_ok=True) creates the complete path and remains safe when the folder already exists. If your process runs in a container, CI worker, or service account, also verify that this runtime user can write there.
#1 Best Overall
Use a unique filename per iteration
A constant name such as screenshot.png points every iteration at the same file. The next save replaces the previous image, leaving you with only the last page. An index with zero padding—page_001.png, page_002.png—sorts naturally and is stable across a run.
If multiple runs share one directory, put a run identifier in the directory name (for example, a timestamp generated by your program) or include it in each filename. Do not place raw URLs or page titles directly into filenames without sanitizing slashes, colons, query characters, and other filesystem-reserved symbols.
Wait for the state you intend to capture
driver.get() returning does not prove that a single-page application, chart, image, or API-backed component has finished rendering. WebDriverWait polls a condition until it succeeds or the timeout expires; Selenium’s documented default polling interval is 0.5 seconds (WebDriverWait API).
Choose a condition that represents the screenshot’s purpose:
Rank #2
- Specific component:
EC.visibility_of_element_located((By.CSS_SELECTOR, "main.dashboard")). - Text or status: wait for an element containing “Loaded” or for a loading indicator to become invisible.
- Image or chart: wait for the component’s container and, if needed, verify its dimensions with a custom predicate.
- Interaction result: click, submit, or select first, then wait for the changed URL, text, or DOM state.
A fixed time.sleep() can be useful for diagnosing a race, but it is usually less dependable than an explicit condition: it may be too short on a slow run and waste time on a fast one.
Choosing the capture scope
Current window screenshot
driver.save_screenshot() captures the current browser window or browsing context. It is appropriate when you want what the user currently sees, including the viewport and the active tab’s state. The Python driver method should not be described as a guaranteed full-page capture; viewport size, browser behavior, and binding support determine what appears.
One element only
When the target is a card, chart, or component, use Selenium’s element screenshot capability rather than cropping a full-window image. Selenium’s window documentation shows separate driver- and element-level screenshot approaches (Working with windows and tabs).
element = wait.until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "article"))
)
path = output_dir / f"article_{index:03}.png"
if not element.screenshot(str(path)):
raise OSError(f"Could not save element screenshot: {path}")
Element capture is useful when browser chrome, surrounding navigation, or unrelated page content should not be included. Make sure the element is displayed and its layout has settled before saving.
Rank #3
Keep results instead of bytes (or work in memory)
Saving directly is simplest for archival jobs. If the next step uploads or transforms images, Selenium also exposes in-memory alternatives:
driver.get_screenshot_as_png()returns PNG bytes.driver.get_screenshot_as_base64()returns a Base64 representation.
For example:
png_bytes = driver.get_screenshot_as_png()
with open(output_dir / f"raw_{index:03}.png", "wb") as image_file:
image_file.write(png_bytes)
Use one output strategy consistently. A successful byte response does not itself prove that a later upload or filesystem write succeeded, so handle those errors separately.
Handling navigation and loop failures
Continue after one bad URL
For batch work, catch errors per URL, record the failure, and continue. Keep the index or a sanitized identifier in the log so a failed item can be retried without confusing its output with another page.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesfailures = []
for index, url in enumerate(urls, start=1):
try:
driver.get(url)
wait.until(EC.visibility_of_element_located((By.TAG_NAME, "body")))
path = output_dir / f"page_{index:03}.png"
if not driver.save_screenshot(str(path)):
raise OSError("save_screenshot returned False")
except Exception as exc:
failures.append({"index": index, "url": url, "error": str(exc)})
if failures:
for failure in failures:
print(failure)
Whether to continue or fail fast depends on the job. A visual regression gate normally stops or marks the build failed; a monitoring batch may collect all failures and report them at the end.
Rank #4
Reset state between pages
Cookies, local storage, open tabs, modal dialogs, and in-page filters can carry state into later iterations. If each URL must be independent, use a fresh browser session, clear the relevant storage, or explicitly reset the application. If a page opens a new tab, switch to the intended window before waiting and saving.
Common symptoms, causes, and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Only one image remains | Every iteration uses the same path. | Add an index, run ID, or sanitized unique key to the filename. |
| No file is created | Parent directory is missing, unwritable, or the API returned False. |
Create the directory, check permissions, and test the Boolean result explicitly. |
| Screenshot shows a spinner or empty panel | Capture happened before meaningful content rendered. | Wait for the application-specific element, text, or loading state. |
| Wrong tab or page is captured | The loop navigated or opened windows without selecting the intended browsing context. | Switch to the correct window handle and verify the URL or title before saving. |
Timeout from WebDriverWait |
The expected condition never became true, the selector changed, or the page failed. | Inspect the page, confirm the selector, increase the timeout only when justified, and capture diagnostics such as URL and HTML. |
| Image is mistaken for full-page output | Driver screenshot covers the current window, not necessarily the entire document. | Use a verified full-page technique for your browser/binding, or capture the required element and document the scope. |
| Local save works but remote execution does not | In a grid or remote driver, the file may be written on the browser node rather than the test runner. | Confirm the grid’s file-transfer behavior and retrieve artifacts through the environment’s supported mechanism. |
Reliability and performance practices
- Reuse the driver carefully: one session avoids startup overhead, but reset state when pages must be isolated.
- Set a bounded wait: every explicit wait needs a timeout so a broken site cannot block the entire batch indefinitely.
- Use deterministic names: map each URL to one predictable artifact and log the mapping.
- Keep diagnostics: on failure, record the URL, current title, current URL, exception, and (when possible) a small HTML or screenshot artifact.
- Separate navigation and capture errors: a timeout, a blocked page, and an I/O failure need different remedies.
- Do not claim reliability from a fixed delay: no single sleep duration is universally correct, and the cited Selenium documentation provides no screenshot failure-rate benchmark.
The Selenium Python API reference identified for this guidance is version 4.49.0. Match examples to the binding installed in your environment and consult that binding’s API when behavior is version-sensitive (Python WebDriver source documentation).
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a clean image or PDF of a URL rather than browser-automation state, ScreenshotNeo provides a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each 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 lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf.
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,
)
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()));
See the parameter reference and options in the ScreenshotNeo documentation. Every plan includes features such as full-page capture with lazy images loaded, CSS-selector element capture, device presets, custom waits, headers and cookies, request blocking, PDF output, signed links, asynchronous jobs, bulk capture of up to 100 URLs per call, and a usage API. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. Sign up free for ScreenshotNeo.
FAQ
What extension should a Selenium screenshot file use?
Use .png with save_screenshot(), as documented by Selenium’s Python API.
Best Value
Can I save screenshots from a remote WebDriver?
Yes, but verify where the remote environment writes files and how it exposes them; local-path assumptions may not hold on a grid.
Is presence_of_element_located always enough?
No. Presence only confirms that a matching node exists. Visibility, text, a completed network-driven state, or another application-specific condition may be required.
Frequently Asked Questions
What extension should a Selenium screenshot file use?
Use .png with save_screenshot(), as documented by Selenium’s Python API.
Can I save screenshots from a remote WebDriver?
Yes, but verify where the remote environment writes files and how it exposes them; local-path assumptions may not hold on a grid.
Is presence_of_element_located always enough?
No. Presence only confirms that a matching node exists; the required condition depends on the page state you need.
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.
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 →

