October 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 NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk6 min

How to Screenshot a Lazy-Loaded Webpage with Selenium

A reliable Selenium screenshot needs more than navigation readiness: trigger lazy loading with the correct scroll target, wait for the content you need, and then capture the right scope.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To capture lazy-loaded content with Selenium, scroll the page—or the nested element that actually scrolls—until the content has loaded, wait for a page-specific condition, and then take the screenshot. A successful navigation or document.readyState check alone does not guarantee that JavaScript-driven content is ready.

Why a Selenium screenshot can miss content

Many pages defer loading images, cards, or other content until the relevant area approaches the viewport. Infinite-scroll pages may fetch more items only after a scroll. Selenium can wait for document readiness, but that is not the same as waiting for an application’s asynchronous content. Selenium’s browser-options documentation cautions that a page may not have finished loading when the ready state returns complete, especially in single-page applications: Browser Options.

As an Amazon Associate I earn from qualifying purchases.

The key is to trigger the page’s loading behavior, then wait for an observable sign that the content you need is ready. The correct scroll target and completion condition depend on the site.

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

Reliable workflow

  1. Identify what needs to appear. Choose a target element, a count of cards, an image, or the page’s loading indicator. Inspect the page to determine whether scrolling happens on the window or inside a nested container.
  2. Navigate and wait for initial structure. Use an explicit wait for a useful starting condition, such as the target list being present. Do not treat navigation returning or document.readyState becoming complete as proof that lazy content is ready. See Selenium’s Waiting Strategies.
  3. Scroll in increments. Scroll the window or the identified inner container. Incremental scrolling gives viewport-triggered loading opportunities as the relevant area approaches view.
  4. Wait for meaningful progress. After a scroll, wait for the desired element to become visible, the item count to increase, an image to finish loading, or a loading indicator to disappear. Prefer such a condition to an arbitrary fixed sleep.
  5. Stop deliberately. For infinite scroll, stop when the target content exists, the page reaches a known boundary, or repeated attempts produce no new items. Selenium provides the script execution and wait mechanisms; it does not prescribe a universal lazy-loading loop.
  6. Capture and inspect. Take the screenshot only after the relevant condition is satisfied. Check the saved image for missing content, clipping, or a page that stopped loading earlier than expected.

Python example: scroll the page and wait for the target

This runnable pattern uses Selenium’s Python binding. Replace the URL and CSS selector with those for the page. It scrolls the window in steps and waits for the target element to become visible after each step. If your site uses a nested scrolling container or infinite scroll without a stable target, adapt the scroll and wait condition as described below.

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
from selenium.common.exceptions import TimeoutException

url = "https://example.com/page"
target_selector = "#content-loaded-below-fold"

options = webdriver.ChromeOptions()
# Uncomment to run without opening a browser window:
# options.add_argument("--headless=new")

driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)

try:
    driver.get(url)

    # Wait for initial page structure, not for every deferred resource.
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "body")))

    target = None
    max_scrolls = 30
    step_px = 700

    for _ in range(max_scrolls):
        # Scroll the window down by one step.
        driver.execute_script("window.scrollBy(0, arguments[0]);", step_px)

        try:
            target = WebDriverWait(driver, 3).until(
                EC.visibility_of_element_located(
                    (By.CSS_SELECTOR, target_selector)
                )
            )
            break
        except TimeoutException:
            # The target may need another scroll to approach the viewport.
            continue

    if target is None:
        raise TimeoutException(
            f"Target did not become visible after {max_scrolls} scrolls: "
            f"{target_selector}"
        )

    # Capture the current browser viewport as a PNG.
    driver.save_screenshot("lazy-page.png")
finally:
    driver.quit()

The loop has a maximum number of scrolls so it cannot run forever. Its short per-step wait is a practical bound, not a claim that the page will always load in that time; adjust the wait to the page and environment. For a more reliable implementation, wait for the actual content-change signal that the page exposes.

Wait for an item count to increase

If each scroll appends items, capture the current count before scrolling and wait until it increases. This is often more useful than waiting for a particular item when you do not know how far down it will appear. For example, use a CSS selector for the repeated cards and a condition that checks whether find_elements returns more elements than the prior count.

Wait for an image to finish loading

If the content element exists but its image is still loading, wait on that image’s DOM state, such as its complete property and a nonzero naturalWidth. An element being present in the DOM does not by itself prove that its image has rendered successfully.

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

Scrolling a nested container

Some pages keep the main document still while a panel or feed scrolls internally. Scrolling window will not trigger that panel’s lazy loading. Find the element whose scrollHeight exceeds its clientHeight, then scroll that element in the page context. Selenium supports JavaScript execution in the currently selected frame or window; see the JavaScript WebDriver API.

container = driver.find_element(By.CSS_SELECTOR, "#scrolling-feed")
driver.execute_script(
    "arguments[0].scrollTop = arguments[0].scrollTop + arguments[1];",
    container,
    600,
)

Use the same approach of checking for a target or meaningful content change after each increment. If the scrollable element is inside an iframe, switch to that frame before locating and scrolling it.

Choose the screenshot scope you need

driver.save_screenshot() captures the current browser screenshot. A WebElement screenshot captures the region within that element’s bounding rectangle; it should not be assumed to capture an entire long page. Selenium’s WebElement API documents the element screenshot scope.

Rank #4
The Web Testing Handbook
  • Used Book in Good Condition

Full-page capture support and behavior depend on the Selenium binding and driver. For example, Selenium’s Ruby screenshot API makes full-page capture conditional on support: TakesScreenshot. Check the API for the binding and driver you actually use, and inspect the result rather than assuming a viewport screenshot includes everything below the fold.

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

Common problems and fixes

  • Screenshot taken immediately after navigation: navigation readiness does not imply that client-side content has appeared. Add an explicit wait for the target or another page-specific condition.
  • Scrolling does not load anything: the page may use a nested scroll container, an iframe, or a different trigger. Identify the actual scrolling element and execute the scroll in the correct frame.
  • The target never becomes visible: confirm the selector matches the intended element, check whether it is hidden behind a collapsed section, and verify that the page has not stopped at a consent dialog or other overlay.
  • Repeated scrolling produces no new items: the page may have reached its boundary, the site may require a different trigger, or loading may have failed. Use a practical stop limit and check the page’s own loading state rather than looping indefinitely.
  • Element appears but image is blank: wait for the image itself to load and verify its dimensions; presence of the containing card is not enough.
  • Full-page output is clipped or unavailable: confirm that the binding and driver support the full-page method you selected. Otherwise, capture the required region in a supported way or use viewport captures after scrolling.
  • Fixed delays work inconsistently: network and application timing vary. Replace sleeps as the sole readiness test with explicit waits for a target, count change, image completion, or disappearance of a loading indicator.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a one-call capture, ScreenshotNeo accepts a URL and returns an image or PDF. For this page, use:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/page -o shot.webp

See the ScreenshotNeo API documentation for request options. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets; these steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page verdict and billing status. Its MCP server gives AI agents tools for taking screenshots, getting page information, and capturing PDFs. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for the free plan.

Frequently Asked Questions

Can Selenium guarantee that every lazy-loaded item has appeared?

No. Selenium supplies scrolling, script execution, waits, and screenshot commands; the site determines when and how it loads content. Your automation needs a page-specific stopping condition.

Does a WebElement screenshot capture the whole page?

No. It captures the visible region inside the element’s bounding rectangle. Use a supported full-page method or another capture approach if you need more than that region.

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.

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.

Leave a Reply

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

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
PC Slower Than It Used to Be?Free scan - under a minute

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.