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

Use one WebDriver session to visit each URL, wait for a page-specific ready condition, call the Go client’s screenshot method, and write the returned PNG bytes with a deterministic name. For larger batches, partition the URL list across independent sessions (or a hosted Selenium Grid), keep a manifest for retries, and treat full-page capture as a separate browser capability rather than assuming the standard endpoint includes the whole document.

What you need before the first capture

  • A recent Go Selenium client, such as the commonly used tebeka/selenium implementation.
  • A compatible browser (for example, Chrome or Firefox) and its matching WebDriver binary. The client documentation requires a working WebDriver installation.
  • A Go module and a writable output directory.
  • A URL list whose entries you can validate and, where necessary, authenticate.

Selenium drives a real browser through WebDriver. The screenshot command operates on the current browsing context; Selenium defines the result as image data encoded in Base64, which the Go binding decodes to bytes for you. The exact method signature and full-page flag are binding/version details, so check the API for the version in your go.mod before compiling.

A reliable bulk-capture workflow

  1. Start one driver session. Create the browser service and capabilities appropriate to your installed browser.
  2. Create the output directory and manifest. Store URL, index, filename, capture time, status, and error text.
  3. Navigate with Get. Record navigation failures separately from screenshot or file-write failures.
  4. Wait for readiness. A page-load return is not proof that a JavaScript application has finished rendering. Wait for a stable selector, disappearance of a loading marker, or another explicit condition.
  5. Capture the current context. Call the binding’s screenshot method and check its error before writing.
  6. Write a deterministic filename. Include the input index and a sanitized host/slug (or a URL hash) so repeated runs cannot overwrite unrelated pages.
  7. Continue recoverable item failures. Keep processing after a bad URL, timeout, or write error; stop for a session-level failure, restart the driver, and retry the remaining items.
  8. Quit the session. Always call Quit, including when a worker exits because of an unrecoverable error.

Complete Go example for a sequential batch

The following program shows the control flow. Replace the service path, browser capability, URL list, and readiness selector with values for your environment. The Screenshot(false) call is the conventional tebeka/selenium shape for a viewport shot; verify the method in your installed client.

package main

import (
    "encoding/csv"
    "fmt"
    "log"
    "os"
    "path/filepath"
    "regexp"
    "strings"
    "time"

    "github.com/tebeka/selenium"
)

const (
    webdriverPort = 9515
    outputDir     = "screenshots"
)

var unsafe = regexp.MustCompile(`[^a-zA-Z0-9._-]+`)

func safeName(raw string) string {
    s := strings.TrimPrefix(strings.TrimPrefix(raw, "https://"), "http://")
    s = unsafe.ReplaceAllString(s, "-")
    s = strings.Trim(s, "-")
    if s == "" { return "page" }
    return s
}

func waitForSelector(d selenium.WebDriver, selector string, timeout time.Duration) error {
    deadline := time.Now().Add(timeout)
    for time.Now().Before(deadline) {
        if _, err := d.FindElement(selenium.ByCSSSelector, selector); err == nil {
            return nil
        }
        time.Sleep(250 * time.Millisecond)
    }
    return fmt.Errorf("selector %q not found within %s", selector, timeout)
}

func main() {
    urls := []string{
        "https://example.com/",
        "https://go.dev/",
    }
    if err := os.MkdirAll(outputDir, 0o755); err != nil { log.Fatal(err) }

    service, err := selenium.NewChromeDriverService("/path/to/chromedriver", webdriverPort)
    if err != nil { log.Fatal(err) }
    defer service.Stop()

    caps := selenium.Capabilities{"browserName": "chrome"}
    driver, err := selenium.NewRemote(caps, fmt.Sprintf("http://127.0.0.1:%d/wd/hub", webdriverPort))
    if err != nil { log.Fatal(err) }
    defer driver.Quit()

    manifest, err := os.Create(filepath.Join(outputDir, "manifest.csv"))
    if err != nil { log.Fatal(err) }
    defer manifest.Close()
    w := csv.NewWriter(manifest)
    defer w.Flush()
    _ = w.Write([]string{"index", "url", "filename", "captured_at", "status", "error"})

    for i, rawURL := range urls {
        filename := fmt.Sprintf("%06d-%s.png", i, safeName(rawURL))
        path := filepath.Join(outputDir, filename)
        capturedAt := time.Now().UTC().Format(time.RFC3339)

        if err := driver.Get(rawURL); err != nil {
            _ = w.Write([]string{fmt.Sprint(i), rawURL, filename, capturedAt, "navigation_error", err.Error()})
            continue
        }
        // Pick a selector that means the page is usable, not merely present.
        if err := waitForSelector(driver, "body", 30*time.Second); err != nil {
            _ = w.Write([]string{fmt.Sprint(i), rawURL, filename, capturedAt, "ready_timeout", err.Error()})
            continue
        }
        png, err := driver.Screenshot(false)
        if err != nil {
            _ = w.Write([]string{fmt.Sprint(i), rawURL, filename, capturedAt, "screenshot_error", err.Error()})
            continue
        }
        if err := os.WriteFile(path, png, 0o644); err != nil {
            _ = w.Write([]string{fmt.Sprint(i), rawURL, filename, capturedAt, "write_error", err.Error()})
            continue
        }
        _ = w.Write([]string{fmt.Sprint(i), rawURL, filename, capturedAt, "ok", ""})
    }
}

For a production worker, set page-load and script timeouts, use a stronger readiness condition than body, and flush the manifest after each row if losing progress during a crash would be costly. Keep navigation, readiness, screenshot, and file-write errors as distinct statuses so retries target the failed stage.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Philips 24 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 241V8LB
  • CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
  • WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
  • A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents

Waiting for JavaScript-heavy pages

Single-page applications often return a document before the useful pixels exist. Choose a condition tied to the page:

  • Wait until a main-content selector exists, such as main[data-loaded="true"].
  • Wait until a known spinner or skeleton element disappears.
  • Wait for a short, bounded delay only when the site has no observable state; combine it with a maximum timeout.
  • When you control the page, expose a deterministic ready marker after data and fonts are rendered.

Do not use an unbounded sleep. It slows every successful URL while still failing unpredictably on slower pages.

Viewport screenshots versus full-page images

The standard WebDriver screenshot endpoint captures the current browsing context—normally the visible viewport. Passing a full-page boolean to a Go binding does not guarantee identical behavior across browsers and versions. Full-page output may require browser-specific support, scrolling and stitching, or a separate service. The Go screenpng project is one concrete implementation pattern: an HTTP server that produces full-page PNG screenshots through Selenium.

Rank #2
Philips 22 Inch Computer Monitor FHD 100Hz VA VESA Flicker-Free, 221V8LB
  • CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
  • 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
  • SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
  • INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
  • THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors

If you implement stitching yourself, fix the viewport size, hide sticky headers between scrolls, capture overlapping segments, and account for device-pixel ratio. Lazy-loaded images must be triggered before each segment; otherwise the stitched file can contain blank regions. Validate the final image dimensions and inspect a few long pages manually.

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

Scaling beyond one browser

Partition the input

Split the URL list into shards and give each shard to an independent driver session. A shared session serializes navigation and also shares cookies, local storage, and cache, which may be wrong for isolated accounts or tenants.

Use a hosted Grid when appropriate

A hosted Selenium Grid supplies managed browser machines and parallel sessions. The Go client documentation describes hosted execution through Sauce Labs; the same architectural choice applies to other Grid providers. Confirm browser versions, geographic location, concurrency limits, and data-handling terms before moving sensitive pages off your network.

Retry with a manifest

Persist one row per URL. On restart, select rows whose status is not ok, and apply a retry limit with backoff. A URL hash or sanitized slug prevents collisions when two URLs have the same final path. If a session-level error occurs, discard that driver, start a fresh one, and resume from the manifest rather than replaying successful rows.

Rank #3
Sale
Dell 24 Monitor - SE2426H - 23.8-inch FHD (1920x1080) 144Hz 1ms Display, in-Plane Switching (IPS) Technology, AMD FreeSync™, TÜV 3-Star 2X HDMI, Tilt
  • Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
  • Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
  • Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
  • In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
  • Ultra-thin bezels: Maximize your viewing experience with thin bezels.

Performance, isolation, and cost considerations

  • Browser startup: Reusing a session is faster than launching a browser per URL, but recycle sessions after a bounded number of pages if memory grows or state becomes contaminated.
  • Parallelism: More workers increase throughput only until CPU, RAM, network, or target-site limits are reached. Start small and observe failure rates.
  • State: Use separate profiles or sessions when cookies, authentication, timezone, or geolocation must not leak between jobs.
  • Assets: Blocking unnecessary ads, trackers, or media can improve speed, but it changes the rendered page. Record such policies in the manifest.
  • Storage: PNG preserves detail but is larger; choose JPEG or WebP only if your downstream comparison tolerates lossy encoding.
  • Ethics and limits: Respect site terms, robots guidance where applicable, authentication boundaries, and rate limits. Bulk capture is not a reason to overload a service.

Common failures and fixes

Symptom Likely cause Fix
Driver will not start Browser and WebDriver versions are incompatible, or the binary path is wrong. Install a compatible pair, verify the executable path and port, and test one manual session.
Get times out Slow server, blocked request, redirect loop, or an overly strict page-load timeout. Capture the navigation error, inspect the URL outside Selenium, raise the bounded timeout where justified, and retry with backoff.
Image is blank or shows a spinner The screenshot ran before the application finished rendering. Wait for a meaningful selector and for loading markers to disappear; do not rely on a fixed sleep alone.
Only the top of a long page appears The endpoint captured the viewport, not the full document. Use browser-specific full-page support, scrolling/stitching, or a service designed for full-page output.
Files overwrite one another Names were derived only from a path or title. Prefix the input index and add a sanitized host/slug or URL hash.
Later URLs show the previous user Cookies or local storage were reused. Use isolated sessions/profiles per worker and clear state when reuse is intentional.
Batch stops after one bad URL Errors are fatal at the outer loop. Log per-item failures and continue; reserve process termination for session-level failures.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. It accepts consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and whether the request was billed. Its MCP server gives Claude, Cursor, and other MCP clients take_screenshot, get_page_info, and capture_pdf tools.

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

One GET request returns PNG, JPEG, WebP, or PDF. The API supports full-page lazy-image loading, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, PDF paper and page options, custom CSS and JavaScript, clicks, selector or network-idle waits, request/resource blocking, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, easing migration.

Use the ScreenshotNeo documentation for authentication and option details. A minimal request is:

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

The same call from 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)

And 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}`);

ScreenshotNeo’s plans are:

Plan 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

Yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

Rank #4
Sale
Samsung 27" Essential S3 (S36GD) Series FHD 1800R Curved Computer Monitor
  • CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
  • SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
  • MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
  • KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
  • INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

FAQ

Does Selenium return a PNG file directly?

The protocol returns Base64-encoded screenshot data. The Go binding exposes decoded bytes, which you write to a file such as .png.

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

Should every URL use a new browser?

No. Reuse a session for throughput when shared state is safe; use separate sessions when isolation or parallelism matters.

Why is a full-page flag not portable?

Full-page behavior is browser- and binding-dependent. The protocol’s baseline operation is the current browsing context, so verify support in the exact browser and Go client versions you deploy.

Best Value
Sale
Sceptre New 22-Inch Gaming Monitor, FHD 1080p, Up to 144Hz, HDMI, DisplayPort, Built-in Speakers, Machine Black (E225W-FW144 Series, 2026)
  • 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
  • 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
  • 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.

Frequently Asked Questions

Can I capture pages behind a login?

Yes, if you are authorized: authenticate in the session, keep credentials out of logs, and isolate sessions when different accounts are involved.

How should I compare screenshots in continuous integration?

Fix browser version, viewport, timezone, locale, and wait conditions; save the manifest and compare only after the same readiness marker is present.

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.

What should a retry record contain?

Keep the URL, input index, filename, timestamp, stage (navigation, readiness, screenshot, or write), error text, and retry count.

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.