Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a documented full-page capture in Selenium, use Firefox’s Python method get_full_page_screenshot_as_file(). It writes the complete document to a PNG and returns False when the file cannot be saved. Chromium needs a browser-specific Chrome DevTools Protocol (CDP) call to capture content beyond the viewport; Selenium’s ordinary save_screenshot() call should not be treated as a cross-browser guarantee of a whole-page image.

Choose the implementation that matches your browser

“Full page” means the screenshot includes document content below the visible viewport, not just what is currently on screen. Selenium exposes this capability differently by browser:

Browser and route How it captures the page Portability and maintenance
Firefox with Selenium Python Firefox-specific full-document methods such as get_full_page_screenshot_as_file() Direct API call; identify Firefox and the Selenium binding explicitly
Chromium with Selenium Python Chrome DevTools Protocol Page.getLayoutMetrics plus Page.captureScreenshot with captureBeyondViewport Browser-specific protocol; verify command details against your Chrome and Selenium versions because tip-of-tree CDP can change without backward-compatibility guarantees
Any driver using ordinary WebDriver screenshot save_screenshot() captures the current browsing context Do not assume it includes the entire document on every driver

The examples below save PNG files. Firefox also provides methods that return PNG bytes or base64 data when you need to upload the image instead of writing it locally.

Firefox: the simplest documented full-page screenshot

Prerequisites

  • Python 3 and a working Firefox installation.
  • Selenium installed in the environment: python -m pip install -U selenium.
  • A writable destination for the PNG file.

The Firefox API reference for Selenium 4.49.0 documents full-document screenshot methods. This example uses the file-saving variant:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
from selenium import webdriver

driver = webdriver.Firefox()
try:
    driver.get("https://example.com")
    saved = driver.get_full_page_screenshot_as_file("page.png")
    if not saved:
        raise OSError("Could not save screenshot")
finally:
    driver.quit()

Save this as a Python file and run it. The browser opens the URL, creates page.png in the current working directory, and quits even if navigation or saving raises an exception. The method expects a PNG path; its documented return value is False for an I/O failure, so checking it catches problems that would otherwise look like a successful run.

Wait for the content you actually want to capture

driver.get() waits for the page load event, but many sites render important content afterward. Add an explicit readiness condition when a known element signals that the page is usable:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

url = "https://example.com"
driver = webdriver.Firefox()
try:
    driver.get(url)
    WebDriverWait(driver, 30).until(
        lambda d: d.execute_script("return document.readyState") == "complete"
    )
    WebDriverWait(driver, 30).until(
        lambda d: d.find_element(By.CSS_SELECTOR, "main")
    )
    if not driver.get_full_page_screenshot_as_file("page.png"):
        raise OSError("Could not save screenshot")
finally:
    driver.quit()

Replace main with a selector that appears only after the content you need is present. If a page fills data through JavaScript, waiting for a specific result, chart, or table is more reliable than adding an arbitrary sleep.

Other Firefox output forms

When a file is not convenient, Firefox’s full-page API also documents methods returning PNG bytes, base64 data, or saving through save_full_page_screenshot. Use bytes for an object-storage upload and base64 when an existing service accepts an encoded image. Keep the browser and Selenium binding in your documentation because these are Firefox-specific APIs, not universal WebDriver commands.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Chromium: use CDP to capture beyond the viewport

For Chrome or another Chromium browser, Selenium can send Chrome DevTools Protocol commands. Page.getLayoutMetrics reports the scrollable CSS content size; Page.captureScreenshot accepts captureBeyondViewport, whose documented default is false. Supplying the content dimensions and enabling the flag produces a full-document PNG in supported versions.

import base64
from selenium import webdriver

url = "https://example.com"
driver = webdriver.Chrome()
try:
    driver.get(url)

    metrics = driver.execute_cdp_cmd("Page.getLayoutMetrics", {})
    size = metrics["cssContentSize"]
    result = driver.execute_cdp_cmd(
        "Page.captureScreenshot",
        {
            "format": "png",
            "captureBeyondViewport": True,
            "clip": {
                "x": 0,
                "y": 0,
                "width": size["width"],
                "height": size["height"],
                "scale": 1,
            },
        },
    )
    with open("page.png", "wb") as image_file:
        image_file.write(base64.b64decode(result["data"]))
finally:
    driver.quit()

This is a Chromium implementation, not a portable Selenium feature. Chrome’s tip-of-tree CDP documentation warns that the protocol changes frequently and does not guarantee backward compatibility. Pin and test the Chrome, driver, Selenium, and CDP combination used in deployment; a command or parameter that works in one release may need adjustment in another.

When the reported dimensions are unusually large

The returned dimensions are CSS pixels. A page with an extremely long feed, a canvas, or oversized transformed content can produce a very large bitmap and consume substantial memory. Capture a specific element, split the document into sections, or use a PDF workflow when a single raster image is impractical.

Why the ordinary Selenium screenshot call is not enough

The standard WebDriver screenshot endpoint and Python’s save_screenshot() usage describe the current browsing context. Some drivers or browser versions may return more than the visible viewport, but Selenium’s general API does not make that a cross-browser full-document guarantee. If your requirement is an entire page, select Firefox’s explicit full-page method or label a Chromium CDP solution as browser-specific.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Always inspect a representative output. Page behavior can change the result: lazy-loaded images may not exist until scrolled into view, fixed headers can appear repeatedly in stitched approaches, and consent dialogs or chat widgets can obscure content. The APIs do not promise identical treatment for every site.

Make dynamic pages deterministic before capture

Wait for a meaningful selector

Prefer a condition tied to the page’s content, such as a product grid, report table, or chart container. A fixed delay is a fallback for animations or delayed third-party widgets, not proof that all network work has finished.

Handle lazy loading

Full-document APIs do not guarantee that every lazy image has loaded. If images are required, scroll through the page first and wait for image completion:

from selenium.webdriver.support.ui import WebDriverWait

# Trigger common viewport-based lazy loaders.
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
driver.execute_script("window.scrollTo(0, 0);")
WebDriverWait(driver, 30).until(
    lambda d: d.execute_script(
        "return Array.from(document.images).every(img => img.complete)"
    )
)

This is practical site-specific handling, not a guarantee for every lazy-loading library. Check the output and add selectors or waits for the page’s own loading state.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Control overlays and animations

Dismiss cookie notices when your test is allowed to do so, hide a known chat launcher with CSS, or wait until an animation finishes. Be careful: removing an element changes what a real visitor would see. Record such choices in the test so the screenshot remains reproducible.

Troubleshooting common failures

Symptom Likely cause Fix
AttributeError for get_full_page_screenshot_as_file The driver is not Firefox, or the binding/version does not expose the Firefox method Use a Firefox WebDriver with a current Selenium binding, or switch to the Chromium CDP example
The PNG is only viewport-sized Used ordinary save_screenshot(), or CDP capture omitted beyond-viewport settings Use Firefox’s full-page method, or set captureBeyondViewport: True and pass the layout dimensions in Chromium
Method returns False Destination path is unwritable, points to a missing directory, or storage failed Create the directory, use an absolute writable path, and check permissions before retrying
Blank or incomplete page Capture ran before client-side rendering, authentication, or data requests finished Wait for a page-specific selector or state; authenticate before capture and verify the resulting image
Images are missing near the bottom Lazy loading was never triggered Scroll to the document end, wait for image completion, return to the top, then capture
CDP command or parameter is rejected Chrome/CDP version mismatch or protocol change Check the deployed browser and Selenium versions, consult the matching CDP documentation, and update the command accordingly
Browser quits before the file is complete Exception handling or process cleanup interrupts the write Write and flush the decoded bytes inside the try block, then quit in finally

Performance, reliability, and file-size considerations

  • Runtime: A full-document capture generally costs more than a viewport shot because the browser must render and encode a larger surface. Waiting for dynamic content can dominate the run time.
  • Memory: PNG stores every pixel. Very tall pages can exceed practical image dimensions or process memory; capture sections or choose a document format when appropriate.
  • Reproducibility: Set a consistent viewport, browser version, timezone, locale, authentication state, and test data. Otherwise responsive breakpoints and personalized content can change the image.
  • Validation: Confirm the file exists, has nonzero size, and can be decoded. For critical jobs, inspect dimensions and retain browser logs so a failed page is distinguishable from a successful blank capture.
  • Security: Treat URLs and page content as untrusted. Do not expose credentials in source code, and isolate browsers that visit user-supplied addresses.

Or skip the browser setup: ScreenshotNeo

If you need an API response instead of maintaining Firefox or Chromium automation, ScreenshotNeo returns a PNG, JPEG, WebP, or PDF from one GET request. It is the first alternative to try when you want predictable capture without managing a browser process: cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page and billing verdict.

Basic cURL request (the API documentation is at https://screenshotneo.com/docs/):

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 full-page jobs

ScreenshotNeo has 63 options, including full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets plus custom viewports, retina scale, image resizing, transparent backgrounds, custom CSS and JavaScript, click-before-capture actions, hidden selectors, waits for a selector, delay, or network idle, ad/tracker/request/resource blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, configurable caching TTL, signed links for public image tags, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Existing parameter names used by other screenshot APIs also work, which can simplify migration.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. That lets an AI agent request a screenshot or PDF without you writing Selenium setup code.

Plans and billing

Plan Monthly price Included shots
Free $0 1,000 per month; no card
Starter $5 3,000
Growth $15 15,000
Pro $39 60,000
Scale $99 250,000
Business $249 1,000,000

Every feature is available on every plan, and yearly billing provides two months free. Start with 1,000 free screenshots a month with no card, then move to a paid plan starting at $5 for 3,000 shots if your volume requires it.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

FAQ

Can I return a full-page screenshot without creating a file?

Yes. Firefox’s documented full-page methods include PNG-byte and base64-returning variants. Decode or upload the returned data in your application instead of using a filesystem path.

Is CDP suitable for a cross-browser test suite?

No. CDP is a Chromium protocol. Keep the Firefox full-page method for Firefox and treat the CDP implementation as a separate Chromium path that is tested against the versions you deploy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does a page look different when captured headlessly?

Responsive breakpoints, fonts, authentication state, animations, lazy loading, and third-party overlays can all alter the rendered document. Fix the viewport and test data, wait for page-specific readiness, and inspect outputs rather than assuming two environments are identical.

When should I choose a PDF instead of a PNG?

Use a PDF when the page is primarily a document and a very tall raster image would be unwieldy. ScreenshotNeo’s capture_pdf MCP tool and API support PDF output; Selenium’s examples here focus on PNG screenshots.

Frequently Asked Questions

Can I return a full-page screenshot without creating a file?

Yes. Firefox’s documented full-page methods include PNG-byte and base64-returning variants. Decode or upload the returned data in your application instead of using a filesystem path.

Is CDP suitable for a cross-browser test suite?

No. CDP is a Chromium protocol. Keep the Firefox full-page method for Firefox and treat the CDP implementation as a separate Chromium path that is tested against the versions you deploy.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does a page look different when captured headlessly?

Responsive breakpoints, fonts, authentication state, animations, lazy loading, and third-party overlays can all alter the rendered document. Fix the viewport and test data, wait for page-specific readiness, and inspect outputs rather than assuming two environments are identical.

When should I choose a PDF instead of a PNG?

Use a PDF when the page is primarily a document and a very tall raster image would be unwieldy. ScreenshotNeo’s capture_pdf MCP tool and API support PDF output; Selenium’s examples here focus on PNG screenshots.

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.