Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk5 min

Take a Full-Page Screenshot with Python and Selenium After Lazy-Loaded Images Finish

A practical Python Selenium workflow for triggering lazy-loaded images, checking completion, and saving a full-page PNG with Firefox WebDriver.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To capture a full-page screenshot after lazy-loaded images have had a chance to load, scroll through the page to trigger them, wait for image completion, then use Firefox WebDriver’s documented full-page screenshot method. Selenium’s ordinary screenshot method captures the current window, not necessarily the whole document.

What you need

  • Python and Selenium installed in an environment with Firefox and a compatible Firefox WebDriver available.
  • A target page you are permitted to automate and capture.

The Firefox Python API documents save_full_page_screenshot(path) and get_full_page_screenshot_as_png() for full-document PNG captures. The documented API is browser-specific; do not assume it works the same way in other browsers. See the Selenium Firefox WebDriver API.

As an Amazon Associate I earn from qualifying purchases.

Run this Python example

Install Selenium with python -m pip install selenium. The example scrolls in viewport-sized steps, waits for image load attempts to complete, checks whether the document height has stabilized, and saves a full-page PNG through Firefox.

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

URL = "https://example.com"
OUTPUT = "page.png"

options = webdriver.FirefoxOptions()
# Optional: headless mode, if supported in your Firefox environment.
# options.add_argument("-headless")

driver = webdriver.Firefox(options=options)

try:
    driver.get(URL)

    # Scroll down by about one viewport at a time. This brings native
    # loading="lazy" images near the viewport so the browser can fetch them.
    previous_height = 0
    stable_passes = 0
    while stable_passes < 2:
        height = driver.execute_script("return document.documentElement.scrollHeight")
        viewport = driver.execute_script("return window.innerHeight")

        y = 0
        while y < height:
            driver.execute_script("window.scrollTo(0, arguments[0])", y)
            time.sleep(0.2)
            y += max(viewport, 1)

        driver.execute_script("window.scrollTo(0, document.documentElement.scrollHeight)")

        # Wait until each image's load attempt has completed. This does not
        # guarantee success: a failed image can also have complete === true.
        WebDriverWait(driver, 30).until(
            lambda d: d.execute_script(
                "return Array.from(document.images).every(img => img.complete)"
            )
        )

        new_height = driver.execute_script("return document.documentElement.scrollHeight")
        if new_height == previous_height:
            stable_passes += 1
        else:
            stable_passes = 0
        previous_height = new_height

    # Optional diagnostic: identify completed images that appear not to have loaded.
    failed_images = driver.execute_script(
        "return Array.from(document.images)"
        ".filter(img => img.complete && img.naturalWidth === 0)"
        ".map(img => img.currentSrc || img.src)"
    )
    if failed_images:
        print("Images that may have failed:", failed_images)

    driver.save_full_page_screenshot(OUTPUT)
    print(f"Saved full-page screenshot to {OUTPUT}")
finally:
    driver.quit()

Replace https://example.com with the page to capture. The loop makes two passes with an unchanged document height before capture, which helps catch pages that grow as content is revealed. It is a practical stability check, not a guarantee that every site’s scripts or visual updates have finished.

Why the order matters

Navigation returning is only an initial readiness point

driver.get() waits according to the page-load strategy and document readiness setting, but dynamically updated applications can continue to change afterward. Selenium cautions that a document reaching readyState complete does not necessarily mean a single-page application has finished loading. See Selenium browser options and page-load strategies.

Scrolling triggers native lazy loading

Browsers defer fetching native lazy-loaded resources until they are near the viewport. Scrolling down through the document is therefore important: a fixed wait while parked at the top may leave off-screen images unfetched. See MDN’s lazy-loading overview.

Completion does not mean success

An image’s complete property indicates that its load attempt has completed, including cases where it failed. Checking naturalWidth helps flag images with no successfully decoded intrinsic width. See MDN’s HTMLImageElement.complete reference.

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

Choose the right screenshot method

Method What it captures When to use it
Firefox save_full_page_screenshot() Full document as PNG Use when running Firefox WebDriver and you need a documented native full-page capture.
Ordinary WebDriver screenshot The current browser window Use for the visible viewport; do not assume it includes the entire document. See Selenium Remote WebDriver API.
Other browser-specific or stitched capture Depends on browser and implementation Verify the current official browser and driver documentation, and test the result on your page.

Adjust the wait for dynamic pages

The sample waits until every image currently in document.images reports completion. For a page with images inserted later by application code, a one-time image check may run before those elements exist. The repeated scroll-and-height pass helps with pages that reveal more content as you move, but it cannot identify every site-specific “finished” condition.

  • If the page has a known element that appears only when content is ready, wait for that element with Selenium’s explicit waits before capture.
  • If the page inserts content after a user action, automate that action before scrolling.
  • If the page continues adding content, use a page-specific condition rather than extending a generic sleep indefinitely.
  • For pages with unusually tall documents, check that the resulting image contains the expected beginning and end of the page.

Troubleshooting

The image is only the visible window

You may be using Selenium’s ordinary screenshot method, which is documented as a current-window capture. Run the capture in Firefox and call save_full_page_screenshot(); verify Firefox WebDriver is the active driver.

Images are missing near the bottom

Make sure the script scrolls to the bottom before waiting. Some pages add new sections as the viewport moves; repeat scrolling after document height grows and use a page-specific readiness condition if needed.

The script times out waiting for images

An image request may never complete, or the page may keep inserting images. Inspect the page and the browser’s network/console diagnostics, then narrow the wait to images relevant to the capture or define a site-specific timeout policy. Do not treat a timeout as proof that all images are broken.

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

An image is complete but appears broken

Check naturalWidth as in the example. A completed request can still fail, so distinguish “finished attempting to load” from “loaded successfully.”

The page changes after the wait

Navigation completion and image completion do not cover all application-driven updates. Wait for a known page-specific signal, repeat the scroll pass if content height changes, and inspect the final screenshot for sticky elements or content that appeared late.

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

Or skip the browser setup

ScreenshotNeo provides a screenshot API and MCP server. Its capture options can remove cookie/consent banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. AI agents can take screenshots through its MCP server. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000.

For a direct PNG/WebP/PDF capture, see the ScreenshotNeo API documentation. Example cURL request:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Frequently Asked Questions

Can Selenium capture a full-page screenshot in Chrome with the same method?

The documented Python full-document methods covered here are Firefox WebDriver methods. Check the current official documentation for the browser and driver you intend to use rather than assuming the Firefox API is portable.

Does scrolling guarantee every image and widget has finished rendering?

No. It triggers viewport-based native lazy loading, but application scripts and site-specific interactions can continue changing the page. Use a page-specific readiness condition when needed.

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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

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.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.