ScreenshotNeo

BlogComparisons

Screenshot API vs Playwright Service for Capturing HTML Pages

Compare a screenshot API with Playwright for capturing HTML pages. See runnable examples, tradeoffs, setup guidance, and how to choose for your workload.

By the ScreenshotNeo team4 October 20269 min read

A screenshot API captures a rendered page through a service request and returns an image. Playwright captures a page through browser automation that your application runs or connects to. Choose an API when you want a request-and-image interface and the provider’s options meet your requirements; choose Playwright when you need browser-level control and can operate the browser environment. Neither is universally faster, cheaper, or more reliable: compare current service terms and test your own pages and workload.

This guide shows how to capture a page with each approach, what to compare, and how to handle dynamic pages, failures, security, performance, and cost. Playwright’s official screenshots guide and Page API reference document its capture method. Browserless is one documented hosted API example: its Screenshot API accepts a URL or inline HTML and can return PNG, JPEG, or WebP. Its endpoint illustrates the API pattern; it does not represent every provider.

1. The difference in one table

Question Screenshot API Playwright
What do you call? A vendor’s HTTP endpoint with a URL or page input. A screenshot method on a Playwright browser Page.
Who runs the browser? The service provider operates the browser execution behind its endpoint. Your application or your chosen browser service operates the browser session.
What do you get? Typically an image response, subject to the endpoint’s documented formats and options. An image buffer or file controlled by the page screenshot options.
Where is control? In the options and workflow the API exposes. In your browser automation code and the Page API.
What must you evaluate? API capabilities, authentication, quotas, terms, and service operations. Browser provisioning, updates, concurrency, monitoring, and application code.

Playwright documents full-page capture, image type, scale, and other screenshot options. An API can offer some overlapping controls, but do not assume options or behavior are interchangeable. Check the current documentation for the specific endpoint you plan to use.

2. Capture with Playwright

The following runnable Node.js example uses Playwright’s Chromium browser, navigates to a page, and saves a PNG. Install the package and its browser first:

npm init -y
npm install playwright
npx playwright install chromium

Save this as screenshot.mjs and run node screenshot.mjs:

import { chromium } from 'playwright';

const browser = await chromium.launch({ headless: true });
try {
  const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
  const response = await page.goto('https://example.com', {
    waitUntil: 'load',
    timeout: 30_000,
  });

  if (!response || !response.ok()) {
    throw new Error(`Navigation failed: ${response?.status() ?? 'no response'}`);
  }

  await page.screenshot({ path: 'page.png', fullPage: true, type: 'png' });
} finally {
  await browser.close();
}

The Playwright screenshot method is invoked on a page after navigation. For applications, keep the browser lifecycle in a try/finally (or equivalent cleanup path), and make timeout and error behavior explicit.

Python example

Install Playwright and Chromium with pip install playwright and playwright install chromium. Save and run:

import asyncio
from playwright.async_api import async_playwright

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=True)
        try:
            page = await browser.new_page(viewport={"width": 1440, "height": 900})
            response = await page.goto(
                "https://example.com", wait_until="load", timeout=30_000
            )
            if response is None or not response.ok:
                status = response.status if response else "no response"
                raise RuntimeError(f"Navigation failed: {status}")
            await page.screenshot(path="page.png", full_page=True, type="png")
        finally:
            await browser.close()

asyncio.run(main())

Choosing navigation and readiness conditions

A navigation event is not proof that every application component has finished rendering. Use a readiness condition that matches the page:

  • load waits for the page load event. It may be delayed by resources and does not guarantee that app-specific data is ready.
  • domcontentloaded waits for document parsing and can be appropriate when you will explicitly wait for a page element afterward.
  • networkidle can help on pages that settle after requests, but persistent polling or analytics may prevent network quiet. Do not use it as a universal readiness signal.
  • For a known app state, wait for a selector or an explicit condition before capturing. For example, await page.locator('[data-ready="true"]').waitFor().

Playwright documents these APIs and their current option details in its Page reference. Confirm exact names and behavior against the version installed in your project.

Useful Playwright screenshot options

Need Option or approach Consideration
Entire scrollable page fullPage: true Very tall pages produce large images and may expose layout or memory limits.
PNG, JPEG, or WebP type where supported by the installed API version Choose format based on fidelity, transparency needs, and output size. Verify format support in the current reference.
Scale scale CSS pixel scaling and device scale affect pixel dimensions and memory. Check current API details.
Viewport-sized output Set the page viewport and capture without full-page mode Use a consistent viewport when comparing pages or generating previews.
Element capture Locate the element and use its screenshot method Wait for the element to exist and be visible; account for clipping and overflow.

For the authoritative list of current screenshot parameters, use the Playwright screenshot API reference.

3. Capture through a hosted screenshot API

A hosted screenshot API moves browser execution behind an HTTP interface. You send a request and handle the returned image. The exact request method, body fields, authentication, formats, options, and limits vary by service.

Browserless documents a POST endpoint at /screenshot, authenticated with an API token, that accepts a URL or inline HTML and can return PNG, JPEG, or WebP. Consult its current endpoint documentation for exact request schema and options. Do not copy a request shape from one provider and assume another accepts it.

General client-side pattern, with endpoint-specific fields deliberately left as placeholders:

curl -X POST 'https://YOUR_SCREENSHOT_API_ENDPOINT' \
  -H 'Authorization: Bearer YOUR_API_TOKEN' \
  -H 'Content-Type: application/json' \
  --data '{"url":"https://example.com"}' \
  --output page.png

The host, token header, HTTP method, and JSON fields above are illustrative placeholders. Replace them with the vendor’s documented values. Treat the response as binary image data; don’t print it as text or assume every non-error response is a valid image.

4. How to choose for your workload

  1. List capture requirements. Record URL versus inline HTML, viewport or full page, format, dynamic readiness, authentication, custom headers, and any page preparation.
  2. Check interface fit. Prefer a request-and-response interface if that is the integration your job or application needs. Prefer Playwright if the workflow requires page interactions or browser automation before capture.
  3. Map operational ownership. With Playwright, decide who provisions and updates browsers, handles concurrency, and monitors failures. With a hosted API, review the provider’s endpoint, quotas, operational terms, and failure behavior.
  4. Evaluate privacy and network access. Before sending sensitive pages or credentials to a hosted service, review where processing occurs, data handling and retention, credential handling, and available controls. The cited endpoint documentation does not settle those vendor-specific questions.
  5. Measure the representative workload. Compare the pages, output sizes, concurrency, and failure cases you actually have. The official method references do not establish a universal price, speed, uptime, or geographic advantage.
  6. Estimate total cost. Include service charges where applicable and the engineering and infrastructure work required to operate a browser. Use current pricing and quotas; no cross-product price comparison is established by the documentation cited here.

5. Reliability, performance, and cost

Reliability

  • Set timeouts for navigation and the overall capture job. A page that never reaches your chosen condition should fail predictably.
  • Validate the response or output: check HTTP status for API calls, and confirm the expected image file or buffer was produced.
  • Retry only transient failures, with a bounded retry count and backoff. Avoid retrying invalid URLs, authorization failures, or deterministic page errors without changing the request.
  • For batches, track each URL independently so one failed capture does not discard successful results.
  • Keep browser cleanup on every Playwright path. For hosted APIs, understand the provider’s error responses and job limits from its documentation.

Performance and throughput

Capture time depends on the page, browser readiness condition, network, output dimensions, and execution environment. Full-page images and high scale increase output work and memory use. For Playwright, reuse a browser process where your architecture supports it, while isolating pages and contexts as needed; cap concurrent captures according to available resources. For a hosted endpoint, check documented concurrency or rate limits and measure latency with your own URL mix. No cross-product benchmark is established by the cited references.

Cost

For a hosted service, calculate expected request volume against current plan pricing, quotas, and overage terms. For self-operated Playwright, include compute, browser maintenance, monitoring, queueing, and engineering time in the estimate. Compare equivalent capture requirements and failure handling. The available documentation does not establish a general cost winner.

6. Common problems and fixes

Symptom Likely cause What to do
Screenshot is blank or content is missing The page had not rendered its app data or images at capture time. Wait for a page-specific selector or state. For lazy-loaded content, scroll or trigger the page’s loading behavior before capture, then confirm content is present.
Navigation times out The site is slow, a resource hangs, or the wait condition never occurs. Choose a bounded timeout and a readiness condition suited to the page. Inspect navigation errors and avoid relying on network idle for pages with persistent requests.
Full-page capture is too large or fails The page is exceptionally tall or output scale is high. Capture a viewport or a specific element, reduce scale if appropriate, or split the page into sections.
API responds with an error instead of an image Wrong method, authentication format, request fields, quota, or endpoint. Check the provider’s current API schema, token, status code, and error body. Save binary output only after confirming a successful response.
Capture differs between runs Dynamic content, time-dependent content, fonts, animations, or changing data. Wait for stable app state, set a consistent viewport, and consider disabling animation or using controlled test data when the page allows it.
Playwright browser fails to launch The browser binary is not installed or runtime dependencies are missing. Run the Playwright browser installation command for your target browser and follow the official installation documentation for the operating system.

7. Or skip the browser setup

If a one-request capture fits your integration, ScreenshotNeo is a screenshot API and MCP server for developers. It returns a PNG, JPEG, WebP, or PDF from one GET request. See the ScreenshotNeo API documentation for options and setup.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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 removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for free and get 1,000 screenshots a month with no card.

8. FAQ

Can an API capture HTML that is not hosted at a public URL?

Some endpoints accept inline HTML; Browserless documents that option. Check the chosen provider’s current schema and consider how embedded assets and scripts are resolved.

Does full-page mean every page element is captured?

It means the capture extends beyond the current viewport according to the tool’s behavior. Lazy-loaded content may require scrolling or other preparation first.

Can I use both approaches in one system?

Yes. A team can use an API for straightforward URL captures and Playwright for workflows requiring custom browser interaction. Keep output expectations and failure handling explicit across both paths.

Which approach is more secure?

That depends on deployment and vendor terms. Review credential handling, page processing, network access, and retention for the specific setup before sending private pages or secrets.