ScreenshotNeo

BlogHow-to

How to set a page load timeout for Selenium screenshots

Set Selenium’s page-load timeout before navigation, then wait for the content your screenshot needs. Includes Python, Java, cURL, Node.js, and recovery tips.

By the ScreenshotNeo team4 October 20267 min read

Set the WebDriver page-load timeout before calling get(). In Python, driver.set_page_load_timeout(30) limits the navigation wait to 30 seconds. After navigation, add an explicit wait for any dynamic content your screenshot depends on; a completed document load does not mean a single-page application has finished updating.

1. Configure the timeout before navigation

This complete Python example creates a browser session, sets a 30-second page-load limit, navigates, waits for a page-specific condition, saves a screenshot, and always quits the browser. Install Selenium and configure ChromeDriver or Selenium Manager as appropriate for your installed Selenium version and environment.

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait

url = "https://example.com"
driver = webdriver.Chrome()
driver.set_page_load_timeout(30)  # seconds

try:
    driver.get(url)
    WebDriverWait(driver, 10).until(
        lambda d: d.find_element("css selector", "main")
    )
    driver.save_screenshot("page.png")
finally:
    driver.quit()

The selector is an example condition, not a universal signal that a page is ready. Replace main with a selector that exists when the content in your screenshot is usable. The official [Selenium Python WebDriver API](https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html) documents set_page_load_timeout(time_to_wait) in seconds and screenshot methods including save_screenshot.

2. Understand which wait is timing out

The page-load timeout bounds navigation while WebDriver waits for the document to reach its configured readiness state. Selenium’s documented default page-load timeout for a new session is 300,000 milliseconds (five minutes), so setting an explicit value makes the navigation bound predictable. [Selenium WebDriver options](https://www.selenium.dev/documentation/webdriver/drivers/options/)

With the normal page-load strategy, navigation waits for document.readyState to become complete. That is a browser document milestone, not a promise that an application has finished rendering its data, animations, lazy images, or client-side updates. [Selenium waiting strategies](https://www.selenium.dev/documentation/webdriver/waits/)

Setting or wait What it bounds or waits for Use it for
Page-load timeout Navigation waiting for the page-load strategy’s readiness state Bounding get() or other navigation
Explicit wait A condition you define, such as an element appearing Waiting for screenshot-specific content
Implicit wait Element lookup retries General element lookup behavior; it is not a navigation timeout
Script timeout Asynchronous script execution Bounding asynchronous WebDriver scripts

Set the shortest navigation limit that fits your expected page and environment, then separately wait for the actual screenshot condition. A shorter limit can expose slow or unstable navigations sooner, but can also fail on legitimate slow pages. The documented five-minute default is an API default, not a performance recommendation.

3. Select a page-load strategy when needed

WebDriver’s page-load strategy changes the document readiness milestone used by navigation:

  • normal: wait for complete.
  • eager: return when the document is interactive.
  • none: do not block navigation on document readiness.

These strategies change when navigation returns; none knows which app-specific content your screenshot requires. If you choose eager or none, use an explicit wait for the target content before capture. Configure page-load strategy in the browser options for your binding and consult the [Selenium options documentation](https://www.selenium.dev/documentation/webdriver/drivers/options/) for the installed version.

4. Handle navigation timeouts deliberately

If navigation exceeds the configured limit, WebDriver raises a timeout error. Decide whether your job should fail, retry, collect diagnostics, or attempt a partial screenshot. A usable partial document is not guaranteed: the result can depend on the browser, driver, and point where navigation stopped.

from selenium import webdriver
from selenium.common.exceptions import TimeoutException

url = "https://example.com"
driver = webdriver.Chrome()
driver.set_page_load_timeout(30)

try:
    try:
        driver.get(url)
    except TimeoutException:
        # Record the failure and decide whether this job should stop.
        print(f"Navigation exceeded the page-load limit: {url}")
        raise

    driver.save_screenshot("page.png")
finally:
    driver.quit()

This example fails the job after logging rather than assuming that a screenshot taken after timeout is valid. If you implement partial-capture recovery, verify it with your browser and driver setup, and label the result so downstream consumers can distinguish it from a successful capture.

5. Binding syntax and units

Python

driver.set_page_load_timeout(30)  # seconds
driver.get(url)
driver.save_screenshot("page.png")

Python takes seconds. Catch Selenium’s TimeoutException around the navigation if you have a recovery path. [Python API](https://www.selenium.dev/selenium/docs/api/py/webdriver_remote/selenium.webdriver.remote.webdriver.html)

Java

import java.time.Duration;

 driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(30));
 driver.get(url);

Remove the leading spaces before the two statements when copying into a method. Current Duration-based Java API syntax uses pageLoadTimeout(Duration); older numeric-time and TimeUnit examples are deprecated in the cited Selenium Java 4.28 API. Check the API version in your project. [Selenium Java timeouts API](https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/WebDriver.Timeouts.html)

JavaScript

The Selenium JavaScript API describes the pageLoad timeout in milliseconds. Setter details can vary with the installed binding version, so use that version’s official API documentation rather than copying a setter from another language. Keep units explicit when translating a value: 30 seconds is 30,000 milliseconds.

6. Capture only after the required content is ready

  1. Set the page-load timeout on the session before navigation.
  2. Navigate to the URL.
  3. Wait for a meaningful condition, such as a result container becoming visible or a loading indicator disappearing.
  4. Capture the screenshot and check that the expected content is present.
  5. On timeout, record the URL and failure stage; retry only if the page or failure mode is plausibly transient.

Prefer conditions tied to the page state over a fixed sleep. A fixed delay can waste time on fast pages and still be too short on slow ones. For lazy-loaded content, the relevant condition may require scrolling or triggering the area before waiting for the image or element.

7. Troubleshooting

Symptom Likely cause What to do
get() raises a timeout The page did not reach the configured readiness state within the limit, or navigation is stalled. Check connectivity, target response, browser logs, and whether the limit suits the workload. Retry selectively; do not assume a partial screenshot is valid.
The screenshot is blank or missing app data Document navigation completed before client-side content became ready. Add an explicit wait for the target element or application state, then confirm it before capture.
The script waits far longer than expected The page-load timeout was not set on the active driver before navigation, or another wait is responsible. Set it on the session that performs get(); inspect explicit, implicit, and script waits separately.
Timeout value behaves at the wrong scale Units differ across language bindings. Python uses seconds; Java uses Duration; JavaScript’s API describes milliseconds. Check the binding documentation.
Page appears ready, but a screenshot condition never passes The selector is wrong, hidden, or does not represent the desired state. Inspect the rendered DOM and choose a condition tied to visible, screenshot-relevant content.
Timeout behavior changes across machines Network, browser, driver, and target timing differ. Log the binding and browser versions, URL, configured limit, and failure stage; keep limits configurable by workload.

8. Performance, reliability, and cost

A page-load timeout is a maximum wait, not a speed improvement. A lower limit can reduce time spent waiting on stalled navigations, while increasing failures for genuinely slow pages. The page-load strategy can let navigation return earlier, but an explicit content wait is still needed when the screenshot depends on later rendering.

For reliable capture jobs, separate navigation success from screenshot-content readiness, record timeout outcomes, and make retry behavior bounded. Avoid retrying every timeout indefinitely: repeated navigation can add load and delay without changing a persistent failure. Selenium itself does not set a per-screenshot service charge; compute costs depend on the browser infrastructure and job runtime you operate.

Or skip the browser setup

For a one-call website screenshot, [ScreenshotNeo](https://screenshotneo.com) provides a screenshot API and MCP server. Its API accepts a URL and returns an image or PDF; see the [ScreenshotNeo API documentation](https://screenshotneo.com/docs/) for options and setup.

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write("shot.webp", res);

The Node.js example uses Bun’s file writer to save the response body; in Node.js, write the returned bytes with node:fs/promises writeFile if needed. ScreenshotNeo removes cookie banners, popups, and chat widgets before capture. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. [Create a free ScreenshotNeo account](https://screenshotneo.com/account/sign-up/).

FAQ

Does the page-load timeout limit how long screenshot saving takes?

No. It bounds page-load completion during navigation. It does not configure a separate limit for screenshot file writing.

Should I use the same timeout for every site?

Not necessarily. Choose a bound that fits the pages and environment in the job, and make it configurable if workloads differ.

Does a timeout mean the browser closed?

No. The navigation command timed out. Your code still needs to manage the WebDriver session and quit it when the job ends.