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

Use a fixed-size worker pool and give every worker its own WebDriver session. Each worker should capture one URL at a time, wait for a condition appropriate to the page, save to a unique path, record the result, and call quit() in a finally block. Selenium has screenshot and browser-session APIs, not a built-in bulk-screenshot command or a universal concurrency limit.

Build a bounded batch with one driver per worker

The example below uses Python’s ThreadPoolExecutor. Set --workers to an explicit limit: that is the maximum number of browser sessions this run attempts to use at once. It is not a Selenium-prescribed value. Choose a limit your machine or remote Grid can support, and respect the sites’ access policies.

Install Selenium with python -m pip install selenium and ensure a compatible browser and driver setup is available. Selenium Manager can manage drivers in supported setups; if your environment requires a separately configured driver, configure that before running the script.

Runnable Python script

Save as bulk_screenshots.py. It reads one URL per non-empty line, writes PNG files under the requested output directory, and writes a JSON Lines manifest after all tasks finish. A SHA-256 digest of each input URL makes filenames distinct without placing an untrusted URL directly in a path.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Epson Workforce ES-50 Compact & Lightweight Mobile Document Scanner
  • PORTABLE SCANNER FOR USE ON-THE-GO — The fastest and lightest mobile single-sheet-fed compact document scanner in its class¹
  • QUICK DOCUMENT SCANNING ― This Epson ultra-fast scanner scans a single page as quickly as 5.5 seconds²; Windows and Mac compatible
  • VERSATILE PAPER HANDLING ― Portable scanner scans documents up to 8.5 x 72 in; Also easily digitizes receipts and ID cards to make accounting, bookkeeping, and organizing simpler
  • INTUITIVE, HIGH-SPEED SOFTWARE — Epson ScanSmart Software³ is a smart tool allowing you to easily scan, review, and save; Stay organized easily with the help of this Epson scanner
  • EASY SETUP — USB-powered connect to your computer for quick and simple scanning; No batteries or external power supply required to operate portable document scanner; Standard Connectivity: USB 2.0
import argparse
import hashlib
import json
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
from urllib.parse import urlsplit

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


def capture(index, url, output_dir, page_load_timeout, ready_timeout, headless):
    driver = None
    output_path = output_dir / f"{index:06d}-{hashlib.sha256(url.encode()).hexdigest()[:16]}.png"
    result = {"index": index, "url": url, "output": str(output_path), "status": "failed", "error": None}

    try:
        options = webdriver.ChromeOptions()
        if headless:
            options.add_argument("--headless")
        options.add_argument("--window-size=1440,1000")
        driver = webdriver.Chrome(options=options)
        driver.set_page_load_timeout(page_load_timeout)
        driver.get(url)

        # A basic readiness condition: the browser reports document.readyState complete.
        # This does not guarantee that application data, lazy images, or animations are ready.
        WebDriverWait(driver, ready_timeout).until(
            lambda d: d.execute_script("return document.readyState") == "complete"
        )

        saved = driver.save_screenshot(str(output_path))
        if not saved:
            raise OSError("WebDriver reported an I/O error while saving the screenshot")
        result["status"] = "success"
    except Exception as exc:
        result["error"] = f"{type(exc).__name__}: {exc}"
    finally:
        if driver is not None:
            try:
                driver.quit()
            except Exception as exc:
                # Preserve a capture error; otherwise report cleanup failure for diagnosis.
                if result["error"] is None:
                    result["error"] = f"DriverQuitError: {type(exc).__name__}: {exc}"
                    result["status"] = "failed"
    return result


def main():
    parser = argparse.ArgumentParser(description="Capture one browser screenshot per URL")
    parser.add_argument("input", help="text file with one URL per line")
    parser.add_argument("--output", default="screenshots", help="output directory")
    parser.add_argument("--workers", type=int, default=3, help="maximum concurrent browser sessions")
    parser.add_argument("--page-load-timeout", type=float, default=45)
    parser.add_argument("--ready-timeout", type=float, default=15)
    parser.add_argument("--headed", action="store_true", help="show browser windows instead of running headless")
    args = parser.parse_args()

    if args.workers < 1:
        parser.error("--workers must be at least 1")
    output_dir = Path(args.output).expanduser().resolve()
    output_dir.mkdir(parents=True, exist_ok=True)
    urls = [line.strip() for line in Path(args.input).read_text(encoding="utf-8").splitlines() if line.strip()]

    results = [None] * len(urls)
    with ThreadPoolExecutor(max_workers=args.workers) as pool:
        futures = {
            pool.submit(capture, i, url, output_dir, args.page_load_timeout,
                        args.ready_timeout, not args.headed): i
            for i, url in enumerate(urls, start=1)
        }
        for future in as_completed(futures):
            results[futures[future] - 1] = future.result()

    manifest = output_dir / "manifest.jsonl"
    with manifest.open("w", encoding="utf-8") as f:
        for result in results:
            f.write(json.dumps(result, ensure_ascii=False) + "n")

    failures = sum(result["status"] != "success" for result in results)
    print(f"Finished {len(results)} URL(s): {len(results) - failures} succeeded, {failures} failed.")
    print(f"Manifest: {manifest}")


if __name__ == "__main__":
    main()

Run it with a URL file such as urls.txt:

python bulk_screenshots.py urls.txt --workers 4 --output ./shots

Use valid, fully qualified URLs, typically including https://. Failures are recorded per URL and do not prevent the remaining URLs from completing. The manifest preserves input order and includes the URL, output path, status, and error message.

Why each task creates its own session

A WebDriver session contains mutable browser state: current page, cookies, navigation, and commands. Sharing one driver among concurrent tasks lets those tasks interfere with one another. This pattern creates a fresh options object and browser for each task, then closes that browser regardless of success or failure.

Choosing and tuning the worker limit

Increasing workers can reduce elapsed time when pages spend much of their time waiting on network activity, but it also increases simultaneous browser memory, CPU, and network use. No official Selenium source sets a universal local worker count. Start conservatively, observe resource pressure and failure rates, then adjust. When running against a remote Grid, coordinate the pool limit with the sessions that deployment can actually provide.

Rank #2
Sale
Brother DS-640 Compact Mobile Document Scanner, (Model: DS640)
  • FAST SPEEDS - Scans color and black and white documents a blazing speed up to 16ppm (1). Color scanning won’t slow you down as the color scan speed is the same as the black and white scan speed.
  • ULTRA COMPACT – At less than 1 foot in length and only about 1. 5lbs in weight you can fit this device virtually anywhere (a bag, a purse, even a pocket).
  • READY WHENEVER YOU ARE – The DS-640 mobile scanner is powered via an included micro USB 3. 0 cable allowing you to use it even where there is no outlet available. Plug it into you PC or laptop and you are ready to scan.
  • WORKS YOUR WAY – Use the Brother free iPrint&Scan desktop app for scanning to multiple “Scan-to” destinations like PC, Network, cloud services, Email and OCR. (2) Supports Windows, Mac and Linux and TWAIN/WIA for PC/ICA for Mac/SANE drivers. (3)
  • OPTIMIZE IMAGES AND TEXT – Automatic color detection/adjustment, image rotation (PC only), bleed through prevention/background removal, text enhancement, color drop to enhance scans. Software suite includes document management and OCR software. (4)

Choose what “ready” means for your pages

The script waits for document.readyState to become complete, a useful baseline but not a promise that every meaningful page element is present. A single-page app may render data after that state, and lazy-loaded images may need scrolling into view. Select a condition that matches the capture you need, such as a known element becoming visible, a specific application state, or a deliberate delay for a known animation. Selenium’s API provides page-load timeout configuration, but no universal rule for application readiness. See the Python WebDriver API.

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

Keep a page-load timeout even when you add a readiness wait: they control different stages. A page-load timeout bounds navigation; a wait timeout bounds the condition you explicitly check. If navigation times out, decide whether your use case should discard that page or attempt to capture its partial state rather than silently treating it as complete.

What Selenium screenshots include

The standard Python save_screenshot(filename) API saves the current window to a PNG file, returns False on an I/O error, and recommends using a full path. The script checks that return value and resolves the output directory to an absolute path. See Selenium’s Python WebDriver API documentation (Selenium 4.50.0 documentation, accessed 2026-10-03).

Rank #3
Sale
Epson Workforce ES-400 II High-Speed Color Duplex Desktop Document Scanner
  • FAST DOCUMENT SCANNING — Document scanner with feeder allows you to speed through stacks with a 50-sheet Auto Document Feeder (ADF); Efficient office scanner to help you scan more productively
  • INTUITIVE, HIGH-SPEED SOFTWARE — Quickly scan with this desktop document scanner; Epson ScanSmart Software lets you easily preview scans, email files, upload to the cloud, and more; Plus, automatic file naming saves even more time
  • SEAMLESS INTEGRATION — Easily incorporate your data into most document management software with the included TWAIN driver; Office document scanner integrates seamlessly with business workflows
  • EASY SHARING — Duplex scanner allows you to scan straight to email or popular cloud storage2 services like Dropbox, Evernote, Google Drive, and OneDrive for simple storage and sharing
  • SIMPLE FILE MANAGEMENT — Scanner allows the creation of searchable PDFs with Optical Character Recognition (OCR) and convert scans to editable Word or Excel files effortlessly; Designed for home and office document scanning

Do not assume that ordinary screenshots capture an entire long page in every browser. Selenium’s Firefox API separately documents full-document screenshot methods; support and method details are browser/driver-specific. Check the Firefox WebDriver API for those methods. If the whole document matters, select and verify a browser-specific full-page method, or capture in sections and stitch them with care about sticky elements and dynamic content.

Use Selenium Grid when local sessions are not enough

A local worker pool runs browser processes on the machine running the script. Selenium Grid routes WebDriver commands to remote browser instances, enabling execution across machines and browser/platform configurations. Grid is optional for a small local batch; it adds deployment and capacity-management work. Selenium describes Grid in its official Grid documentation.

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

To connect a worker to Grid, replace the local driver construction with a remote session using your Grid command-executor URL and browser options:

grid_url = "http://your-grid-host:4444"
options = webdriver.ChromeOptions()
options.add_argument("--headless")
driver = webdriver.Remote(command_executor=grid_url, options=options)

Place this initialization inside the worker so every concurrent task still gets its own remote session, and keep the same quit() cleanup. The endpoint above is an example address, not a public Selenium service. Configure the worker ceiling based on the capacity of your Grid deployment, not on an assumed Selenium default. The Remote WebDriver API documents the remote server connection and session capabilities.

Rank #4
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
  • Scanner type: Document
  • Connectivity technology: USB
  • With Auto Scan Mode, the scanner automatically detects what you're scanning
  • Digitize documents and images

Output, reliability, and operating cost

  • Prevent collisions: use a stable per-input identifier, as the script does, rather than naming every file after only the hostname. If you change the naming scheme, account for duplicate URLs and distinct URLs with similar paths.
  • Keep result writes coordinated: the example gathers results in the main thread and writes one manifest after workers finish. If writing results incrementally from workers, protect shared output with a lock or use a thread-safe queue.
  • Make retry policy explicit: Selenium does not decide whether a failed URL should be retried. For transient network errors, add a bounded retry count and backoff; avoid retry loops that multiply load on an unavailable site.
  • Manage disk use: large batches produce many image files and a manifest. Ensure the destination has space, and define retention or cleanup separately from capture.
  • Respect targets: concurrent navigation can place load on sites. Use a low worker count where appropriate, and follow each site’s terms and access rules.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common failures

Browser or driver cannot start

Check that the browser is installed and supported by the installed Selenium setup, and inspect the exception recorded in the manifest. In restricted environments, install/configure a compatible driver or browser explicitly and confirm the process has permission to launch it.

Navigation or readiness timeout

Some sites are slow, hang on resources, or never reach the condition your application requires. Increase the relevant timeout only if the workload warrants it; otherwise record the failure and continue. For apps that render after navigation completes, replace the generic readiness condition with a wait for a stable, task-specific element.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Screenshot file is missing or reported as failed

Confirm the output directory is writable and that the path is valid. Selenium recommends a full path for save_screenshot; the script uses one and treats a False return as failure. Check available disk space if failures occur only later in a large batch.

Best Value
Sale
ScanSnap iX2500 Wireless or USB High-Speed Document Scanner, Black
  • OUR MOST ADVANCED SCANSNAP. Large touchscreen, fast 45ppm double-sided scanning, 100-sheet document feeder, Wi-Fi and USB connectivity, automatic optimizations, and support for cloud services. Upgraded replacement for the discontinued iX1600
  • CUSTOMIZABLE. SHARABLE. Select personalized profiles from the touchscreen. Send to PC, Mac, mobile devices, and clouds. QUICK MENU lets you quickly scan-drag-drop to your favorite computer apps
  • STABLE WIRELESS OR USB CONNECTION. Built-in Wi-Fi 6 for the fastest and most secure scanning. Connect to smart devices or cloud services without a computer. USB-C connection also available
  • PHOTO AND DOCUMENT ORGANIZATION MADE EFFORTLESS. Easily manage, edit, and use scanned data from documents, receipts, photos, and business cards. Automatically optimize, name, and sort files
  • AVOIDS PAPER JAMS AND DAMAGE. Features a brake roller system to feed paper smoothly, a multi-feed sensor that detects pages stuck together, and skew detection to prevent paper damage and data loss

Pages look incomplete or images are absent

document.readyState does not ensure lazy content or asynchronous application data has loaded. Wait for the relevant content, scroll to trigger lazy loading when needed, and verify the screenshot extent supported by the selected browser and driver.

Too many sessions fail under load

Reduce --workers and observe whether local resource pressure or remote Grid capacity is the constraint. A concurrency limit bounds sessions, but it cannot guarantee that target sites, network conditions, or browser processes will succeed.

Or skip the browser setup

ScreenshotNeo offers a screenshot API and MCP server for this workflow. One GET request returns an image or PDF, and its API accepts the common screenshot-API parameter names, which can ease a switch from another service. Cookie/consent banners, newsletter popups, and chat widgets are removed before capture by default; those steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. AI agents can use its MCP tools, including take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

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

Example request for one URL (replace the key and target URL). See the ScreenshotNeo API documentation for setup and options:

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

For a URL list, issue one request per URL while applying your own bounded concurrency and recording each response. Sign up for 1,000 free screenshots a month with no card.

Frequently Asked Questions

Does Selenium set a maximum number of parallel screenshot workers?

No. Set an explicit limit in your application and base it on available local or Grid capacity and the target sites’ policies.

Can the same Selenium driver be shared by several worker threads?

Use one independent WebDriver session per concurrent worker so simultaneous tasks do not compete over browser state.

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

Quick Recap

Bestseller No. 4
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Canon Canoscan Lide 300 Scanner (PDF, AUTOSCAN, Copy, Send)
Scanner type: Document; Connectivity technology: USB; With Auto Scan Mode, the scanner automatically detects what you're scanning
$75.00

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.