ScreenshotNeo

BlogComparisons

Browserless vs. Browserless Alternatives for Product Price Screenshot Jobs

Compare Browserless, Cloudflare Browser Run, self-hosted browsers, and ScreenshotNeo for capturing product prices. Choose a workflow, configure it, and validate the result.

By the ScreenshotNeo team4 October 202610 min read

For a one-off or recurring product-price screenshot that only needs to render a URL, start with a stateless screenshot API. Browserless provides a direct REST /screenshot endpoint; Cloudflare Browser Run offers a comparable Quick Action. Choose a browser-session service or self-hosted Playwright/Puppeteer when the workflow must dismiss dialogs, select a variant, set a location, sign in, or otherwise interact with the page. No controlled benchmark in the available evidence establishes which service is faster, more accurate, less expensive overall, or more successful against anti-bot defenses.

For a managed API with clean screenshots, per-response billing verdicts, and a simple one-call integration, ScreenshotNeo is the alternative to try first. It accepts a URL and returns an image or PDF; the section below includes its code and trade-offs.

1. Decide what the job needs

Requirement Suitable starting point What to verify
Render one URL and save an image Browserless REST or Cloudflare Quick Actions Authentication, format, viewport, wait behavior, retries, and output validation
Capture only the price block A screenshot endpoint with selector or clipping support The selector is stable and includes currency, unit, and relevant context
Dismiss a dialog, choose a size, or set a region Playwright/Puppeteer browser session Session lifecycle, cookies, locale, and reproducible interaction steps
Reuse existing browser automation code Managed Browserless or Cloudflare browser session Library compatibility, concurrency, connection handling, and debugging
Control deployment and browser infrastructure Self-host Chromium with Playwright/Puppeteer Operations, browser updates, scaling, network access, and security ownership

Product pages can show different prices by region, account, stock, selected variant, promotion, or time. A successful HTTP response and an image file only show what rendered in that browser context at that moment; they do not prove it is the intended price. Define the target state and validate it.

2. Capture a product page with Browserless REST

Browserless documents POST /screenshot for a URL or raw HTML. Authenticate with the token query parameter and pass Puppeteer-style screenshot settings in options. The response is image bytes. See the Browserless Screenshot API documentation.

cURL

curl --fail-with-body -X POST \
  "https://production-sfo.browserless.io/screenshot?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Cache-Control: no-cache" \
  -d '{
    "url": "https://example.com/product",
    "options": {
      "fullPage": true,
      "type": "png"
    },
    "scrollPage": true
  }' \
  --output product.png

Python

import os
import requests

endpoint = "https://production-sfo.browserless.io/screenshot"
payload = {
    "url": "https://example.com/product",
    "options": {"fullPage": True, "type": "png"},
    "scrollPage": True,
}
response = requests.post(
    endpoint,
    params={"token": os.environ["BROWSERLESS_TOKEN"]},
    headers={"Cache-Control": "no-cache"},
    json=payload,
    timeout=90,
)
response.raise_for_status()
content_type = response.headers.get("content-type", "")
if "image/" not in content_type:
    raise RuntimeError(f"Expected an image, got {content_type}: {response.text[:500]}")
with open("product.png", "wb") as image:
    image.write(response.content)

Node.js

import { writeFile } from "node:fs/promises";

const token = process.env.BROWSERLESS_TOKEN;
if (!token) throw new Error("Set BROWSERLESS_TOKEN first");
const endpoint = new URL("https://production-sfo.browserless.io/screenshot");
endpoint.searchParams.set("token", token);

const response = await fetch(endpoint, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Cache-Control": "no-cache",
  },
  body: JSON.stringify({
    url: "https://example.com/product",
    options: { fullPage: true, type: "png" },
    scrollPage: true,
  }),
  signal: AbortSignal.timeout(90_000),
});
if (!response.ok) {
  throw new Error(`Browserless HTTP ${response.status}: ${(await response.text()).slice(0, 500)}`);
}
const contentType = response.headers.get("content-type") ?? "";
if (!contentType.includes("image/")) {
  throw new Error(`Expected an image, got ${contentType}`);
}
await writeFile("product.png", Buffer.from(await response.arrayBuffer()));

Replace the example URL and supply the token through an environment variable or secret manager. Do not commit the token or expose it in client-side code. The code checks status and content type so a JSON error response is not silently saved with a PNG extension.

Useful Browserless capture settings

  • options.fullPage: capture the full scrollable page rather than only the viewport. Pair with top-level scrollPage: true when lazy-loaded content needs scrolling to appear.
  • options.type: choose png, jpeg, or webp as supported by the endpoint. JPEG quality is relevant to lossy output, not PNG.
  • options.viewport and device scale factor: choose a stable viewport and pixel density so captures are comparable over time.
  • options.clip: define a fixed rectangle when the target area is known in advance. A selector is usually less brittle than hand-maintained coordinates.
  • Top-level selector: capture a particular element by CSS selector; the endpoint waits for the element and crops to its bounds.
  • html: render supplied HTML instead of navigating to a URL. Do not send url in the same request.
  • Wait configuration and navigation options: wait for the relevant page state or selector rather than assuming navigation completion means the price has loaded.
  • rejectResourceTypes and rejectRequestPattern: block selected resources or requests when appropriate; verify that the price still renders.
  • bestAttempt: allow the request to continue when asynchronous events fail or time out, where supported. Still validate the output.
  • Launch settings: Browserless documents launch parameters such as browser configuration. Use its launch parameters guide for supported values and encoding.

The endpoint documentation describes additional Puppeteer-style options, waiting, navigation configuration, and troubleshooting in its API reference. Keep the capture settings explicit in monitoring jobs; changing viewport, wait condition, or selector can change the evidence collected.

3. Use Cloudflare Browser Run as a stateless alternative

Cloudflare Browser Run Quick Actions expose a screenshot REST endpoint and Worker binding for simple stateless tasks. For interactions or persistent browser sessions, Cloudflare documents Puppeteer, Playwright, CDP, and Stagehand routes. See Quick Actions and the get-started guide.

cURL example

curl --fail-with-body -X POST \
  "https://api.cloudflare.com/client/v4/accounts/YOUR_ACCOUNT_ID/browser-rendering/screenshot" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/product",
    "screenshotOptions": {"fullPage": true},
    "viewport": {"width": 1365, "height": 900},
    "gotoOptions": {"waitUntil": "domcontentloaded", "timeout": 30000},
    "waitForSelector": ".product-price"
  }' \
  --output product.png

Create a Cloudflare API token with Browser Rendering - Edit permission and substitute your account ID and token. Check the response content type and status in production before treating the output as an image. The exact accepted screenshot fields are documented in the current endpoint reference.

When to move from Quick Actions to a browser session

Use a scripted session when the job must perform a sequence such as opening a product, selecting a variant, setting a delivery region, or closing a consent dialog. A session lets the automation issue browser commands between navigation and capture; the extra control means you must also manage session closure, timeouts, concurrency, and cleanup. Cloudflare documents sessions controlled by Puppeteer, Playwright, CDP, or Stagehand; Browserless supports managed browser WebSocket routes for Puppeteer or Playwright. See the Browserless overview.

4. Consider self-hosted Playwright or Puppeteer

Self-hosted Chromium is an operational alternative for a team prepared to run browser infrastructure. Browserless documents an open-source Docker option in its OpenAPI overview. A self-hosted workflow gives the team responsibility for browser installation and updates, process isolation, capacity, networking, retries, observability, and security. This is not automatically cheaper: compare infrastructure and engineering effort against the workload and current managed-service terms.

5. Validate that the screenshot proves the intended price

  1. Specify the state. Record the exact product URL, desired variant, region, account state, viewport, and capture time. Avoid comparing captures from different states as if they were equivalent.
  2. Wait for the price itself. Configure a selector wait for the price element when available. A document load event can happen before client-side price data is ready.
  3. Trigger lazy content where needed. Scroll before full-page capture if the page loads images or sections only as they enter view. Browserless documents scrollPage for this purpose.
  4. Inspect the image. Check that the price, currency, selected variant, and surrounding label are visible. A tight element crop can omit context such as per-unit pricing or a sale qualifier.
  5. Classify failures separately. Detect blank output, challenge or access-denied pages, missing price blocks, incomplete rendering, and stale content. Store status and diagnostic metadata with each capture.
  6. Keep evidence reproducible. Store capture time and configuration with the image. If the image is used to alert on price changes, compare like-for-like regions, variants, viewport, and page state.

Browserless explicitly lists blank screenshots, CAPTCHA pages, access-denied pages, and missing or broken elements as possible signs that a site is blocking automation. Its documentation describes an /unblock route, but the reviewed evidence does not establish comparative success rates. Test representative sites lawfully and do not assume a screenshot provider will bypass a target site’s controls.

6. Compare cost, performance, and reliability

Option Cost evidence available here Operational considerations
Browserless Detailed current rate table was not inspected; consult its current official pricing page before estimating total cost. REST suits stateless tasks; browser sessions suit scripted workflows. Include run volume, execution time, retries, and session needs in the estimate.
Cloudflare Browser Run Published Workers Paid terms list 10 browser hours per month, then $0.09 per additional hour. Browser Sessions list 10 concurrent browsers averaged monthly, then $2.00 per additional browser. Quick Actions charge by browser hours; sessions also have concurrency terms. Pricing is time-sensitive; verify current terms and estimate from your own workload.
Self-hosted browser No comparable dollar estimate is established by this evidence. Account for compute, operations, browser maintenance, scaling, and engineering time.
ScreenshotNeo Free: 1,000 screenshots/month with no card. Paid: $5 for 3,000, $15 for 15,000, $39 for 60,000, $99 for 250,000, and $249 for 1,000,000. Yearly billing gives two months free. Only clean shots are billed; responses identify page verdict and billing status. Every feature is on every plan.

Cloudflare’s published rates and allowances above are plan terms, not a quote; check the current Browser Run pricing page. Estimate total cost using expected monthly captures, browser run time, peak and average concurrency, retries, and the current plan’s billing rules. The reviewed dossier does not support a Browserless price comparison or a benchmark between providers.

For performance, keep the viewport and wait policy no larger or longer than the task requires, avoid loading unnecessary resources only when doing so does not affect the page state, and reuse browser sessions for related steps when the chosen service supports it. These are workflow choices, not claims that one provider is faster. For reliability, use bounded retries for transient failures, preserve diagnostic responses, and validate image content instead of treating every HTTP success as a valid price capture.

7. Or skip the browser setup

ScreenshotNeo offers a GET screenshot API and developer documentation. One request returns an image; replace the target URL and use your API key:

cURL

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

ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say the page verdict and whether the request was billed. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month, with no card required.

8. Troubleshooting

Symptom Likely cause What to do
HTTP error or JSON saved as an image Bad token, account or endpoint configuration, request rejected, or non-image error response. Check status and response body before writing bytes; verify the endpoint, token, content type, and request schema.
Blank or mostly white capture Page load failure, automation blocking, script error, or capture before content appears. Inspect the page state and provider response; wait for the price selector and test the URL in a normal browser context. Browserless identifies blank output as a possible blocking symptom.
CAPTCHA, challenge, or 403 appears in the image The target is blocking or challenging the automated browser. Do not mark the capture as a valid price. Review the target’s access rules and test permitted methods; avoid assuming another service will succeed.
Price is missing but the page is otherwise visible Price rendered late, requires a variant or location, or selector changed. Wait for the relevant selector, perform the required interaction in a browser session, and update selectors after inspecting the page.
Images or lower sections are missing Lazy loading has not been triggered or the screenshot is viewport-only. Use full-page capture and scroll before capture when supported; wait for important image or section selectors.
Capture differs between runs Variant, region, promotion, stock, account, time, or viewport changed. Fix the capture context and record it with each result. Treat genuine price changes separately from rendering differences.
Request times out Slow navigation, delayed scripts, unavailable resources, or overly strict wait conditions. Set an appropriate bounded timeout, wait for the target element rather than every network request, and classify repeated failures instead of retrying indefinitely.
Cloudflare Quick Action returns a wait timeout A configured navigation, selector, or additional wait exceeded its limit. Review the separate timeout settings and limits in the timeout documentation; simplify the wait condition or investigate the target.
Capture includes cookie banner or popup The service did not dismiss it, or it is not covered by that service’s configured behavior. For a scripted session, handle the dialog explicitly where permitted. ScreenshotNeo removes supported consent platforms and common newsletter popups and chat widgets before capture.
Cloudflare request fails due to plan limit Browser hours, request rate, timeout, or concurrency limits may apply. Check current limits and pricing; lower concurrency or request rate, or review the account plan.

9. FAQ

Does a screenshot confirm that a price is correct?

No. It is visual evidence of what rendered in a particular browser context at capture time. Validate the selected product state and price content.

Should I use a screenshot or extract structured price data?

Use screenshots when visual evidence or a visual comparison is the goal. For recurring price monitoring, also consider structured extraction; Browserless documents separate content and scraping APIs, but the evidence here does not compare their accuracy with screenshots.

Is this an exhaustive ranking of browser services?

No. The supported comparison covers Browserless, Cloudflare Browser Run, self-hosted browsers, and ScreenshotNeo. The available research does not establish a broader market ranking.

Can I compare captures from different regions or variants?

Only if the difference is intentional. Region, account state, stock, promotion, variant, and capture time may affect what the page displays, so preserve those inputs when comparing results.