InvalidSessionIdException means Selenium no longer recognizes the WebDriver session ID as active. In a screenshot loop, first check whether driver.quit() ran before the next iteration, whether a with block ended too soon, or whether the only browser window was closed. Keep the driver alive for the entire loop and call quit() only when the work is complete. If those lifecycle checks are sound, use the traceback and browser or remote-session logs to investigate; the exception name alone does not identify the cause.
Keep one driver session alive for the whole loop
Create the driver before the loop, perform each navigation and screenshot while that driver is active, then quit it after the loop. A finally block ensures cleanup also runs if navigation or saving raises an exception.
from pathlib import Path
from selenium import webdriver
urls = [
"https://example.com/one",
"https://example.com/two",
]
out_dir = Path("screenshots")
out_dir.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
for index, url in enumerate(urls, start=1):
driver.get(url)
saved = driver.save_screenshot(str(out_dir / f"page-{index}.png"))
if not saved:
raise OSError(f"Could not save screenshot {index}")
finally:
driver.quit()
This ordering keeps a single live session through every iteration. Do not put driver.quit() inside the loop if later iterations use that same driver. Selenium documents that commands cannot be sent to a driver instance after its session has ended: Driver sessions.
If you use a context manager
A WebDriver context manager quits the browser when its indented block ends. Put the entire loop inside the block:
#1 Best Overall
from pathlib import Path
from selenium import webdriver
urls = ["https://example.com/one", "https://example.com/two"]
out_dir = Path("screenshots")
out_dir.mkdir(parents=True, exist_ok=True)
with webdriver.Chrome() as driver:
for index, url in enumerate(urls, start=1):
driver.get(url)
if not driver.save_screenshot(str(out_dir / f"page-{index}.png")):
raise OSError(f"Could not save screenshot {index}")
If the loop is outside the with block, the browser has already been quit when the loop tries to use it.
Check whether a window was closed
driver.close() closes the current window; driver.quit() ends the whole session. If the current window was the only one, there is no remaining browsing context for later navigation or screenshots. When closing one of several windows, switch to a still-open handle before continuing. Selenium’s guidance on window and tab handling explains this distinction: Working with windows and tabs.
Rank #2
# After closing a non-final window, switch to a remaining one:
remaining_handles = driver.window_handles
if remaining_handles:
driver.switch_to.window(remaining_handles[0])
Do not send further commands if there are no valid window handles. If the session itself has ended, create a new driver session rather than trying to revive the old one.
Separate session failures from screenshot file errors
driver.save_screenshot(path) saves the current window as a PNG and returns a Boolean. A return value of False points you toward the output path or file I/O; it is different from a session that Selenium no longer recognizes. Check the return value and ensure the destination directory exists. See the Python WebDriver API for the method’s behavior.
Rank #3
Diagnose the first failing command
- Find premature cleanup. Search the loop and helper functions for
quit(), context-manager boundaries, early returns, and exception handlers that may clean up before the next screenshot. - Check window handling. Search for
close()and verify that the active window handle is still open before the next navigation or capture. - Read the full traceback. Identify whether the first failed command is navigation, window switching, or
save_screenshot. If the screenshot method returnsFalsewithout raising this exception, investigate the output path and filesystem instead. - Inspect process and remote logs if lifecycle is correct. A browser or driver process failure, or deletion/timeout of a remote session, is possible. For Selenium Grid or another remote WebDriver service, check the relevant node or provider logs along with the client traceback.
The Selenium Python exception reference defines InvalidSessionIdException as being thrown when the given session ID is not in the list of active sessions: Selenium exceptions API. That definition does not reveal whether the session was deliberately quit, lost with a window or process, or removed remotely.
Recover without masking the problem
A retry or sleep does not restore a deleted session. If the browser session is gone, create a replacement driver and explicitly restore the URL, cookies, authentication, or other state your workflow needs before continuing. If the session is still active, fix the lifecycle or window issue at its source rather than wrapping every screenshot in retries that reuse an invalid driver.
Rank #4
Or skip the browser setup
If your goal is to capture URLs rather than exercise a browser workflow, ScreenshotNeo provides a website screenshot API and MCP server. Its one-request API can return a screenshot or PDF; the cleanup options accept consent banners and remove supported consent platforms, newsletter popups, and chat widgets before capture. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed.
For setup and parameters, see the ScreenshotNeo API documentation. Example cURL request:
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/one -o shot.webp
ScreenshotNeo also has MCP tools for AI agents, including take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card required.
Quick Recap
Best Value
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.




