ScreenshotNeo

BlogComparisons

Puppeteer vs Screenshot APIs for Competitor Landing Page Audits

Choose Puppeteer for custom browser interactions and a screenshot API for URL-based capture. Learn how to make competitor landing page audits repeatable.

By the ScreenshotNeo team4 October 20269 min read

Use Puppeteer when an audit depends on scripted browser interaction, custom page-state logic, or control over the browser workflow. Use a hosted screenshot API when a URL plus capture settings is enough and you prefer to call a managed HTTP endpoint. Both can capture viewport and full-page images; the useful distinction is who controls the browser and how much site-specific logic the audit needs.

For consistent results, decide what page state and capture scope you need, set the viewport and output options explicitly, and save capture metadata beside each image. The available documentation describes capabilities, but does not establish a price, reliability, latency, or visual-accuracy winner.

1. Decide what the audit must capture

Before choosing a tool, define the observation you want to compare. A landing-page audit might track the initial viewport, the full page, a hero section, or a fixed region. It might also need to capture a known state after dismissing a banner or opening a menu.

Audit need Good starting point Why
One URL and a standard viewport or full-page image Hosted screenshot API A request can specify the URL and capture settings.
Clicking, dismissing, or otherwise interacting with the page first Puppeteer or another browser library You write the interaction and capture sequence.
Capture a particular element or clip Either Puppeteer documents element screenshots and clip options; Browserless documents selector capture.
Control how the browser is launched and operated Puppeteer The calling program owns the browser lifecycle in the documented workflow.
Send capture work to a managed HTTP endpoint Hosted screenshot API The service exposes a screenshot endpoint, though its operational guarantees and limits need to be checked separately.

This is a capability mapping, not a benchmark. The research does not provide comparable measurements for cost, speed, uptime, or visual accuracy.

2. Capture with Puppeteer

Puppeteer gives your program a browser/page workflow: launch a browser, navigate to the page, wait for the state you need, take a screenshot, and close the browser. Its screenshot methods include Page.screenshot() and element-level ElementHandle.screenshot().

Runnable Node.js example

Install Puppeteer in a Node.js project with npm install puppeteer. Save the following as capture.mjs and run it with node capture.mjs https://example.com. Replace the example URL with the competitor landing page you are authorized to audit.

import puppeteer from 'puppeteer';

const url = process.argv[2] ?? 'https://example.com';
const browser = await puppeteer.launch({ headless: true });

try {
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 1000, deviceScaleFactor: 1 });
  await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });

  // Use fullPage: false for a viewport capture; true captures the full page.
  await page.screenshot({ path: 'landing-page.png', fullPage: true, type: 'png' });
} finally {
  await browser.close();
}

networkidle2 is one possible navigation condition, not a guarantee that every page has finished rendering. Some sites maintain long-running network requests, while others reveal content only after scrolling or interaction. Choose a wait strategy that matches the state your audit intends to compare.

Capture a specific element

Use an element screenshot when the comparison concerns a stable section, such as the hero. Wait for the selector, resolve it, then capture that element.

await page.waitForSelector('main .hero', { timeout: 15000 });
const hero = await page.$('main .hero');
if (!hero) throw new Error('Hero selector did not match an element');
await hero.screenshot({ path: 'hero.png', type: 'png' });

Selectors are site-specific. If the markup changes, the selector can stop matching or identify a different element, so keep the selector and capture date with the audit record.

Capture a fixed clip or choose output options

Puppeteer screenshot options include full-page capture, a clip rectangle, output type, and quality. The documented fullPage default is false. Set these values rather than depending on defaults when comparing images.

await page.screenshot({
  path: 'hero-clip.jpeg',
  type: 'jpeg',
  quality: 85,
  clip: { x: 0, y: 0, width: 1440, height: 900 },
  fullPage: false
});

Use quality with JPEG output. Choose PNG when preserving lossless pixel detail matters; the dossier does not establish a universally best format or quality value.

3. Capture through a hosted screenshot API

A hosted API accepts a URL and capture settings over HTTP. Browserless documents a POST /screenshot endpoint with viewport/output controls, full-page capture, and element selectors. Check the provider’s current documentation for exact authentication, request fields, quotas, response handling, and service limits; those details are not established uniformly by the research dossier.

cURL example

The following illustrates an HTTP POST shape. The endpoint’s exact schema and authentication vary by provider; match the request body and credentials to that provider’s current screenshot API documentation.

curl -X POST 'https://production-sfo.browserless.io/screenshot?token=YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data '{
    "url": "https://example.com",
    "options": {
      "fullPage": true,
      "type": "png"
    }
  }' \
  --output landing-page.png

Python example

With a provider that accepts the illustrated JSON shape, Python’s requests library can save the binary response. Confirm the endpoint and schema before using this request with a provider.

import requests

endpoint = 'https://production-sfo.browserless.io/screenshot'
params = {'token': 'YOUR_TOKEN'}
payload = {
    'url': 'https://example.com',
    'options': {'fullPage': True, 'type': 'png'},
}

response = requests.post(endpoint, params=params, json=payload, timeout=90)
response.raise_for_status()
with open('landing-page.png', 'wb') as image_file:
    image_file.write(response.content)

Node.js example

const endpoint = new URL('https://production-sfo.browserless.io/screenshot');
endpoint.searchParams.set('token', 'YOUR_TOKEN');

const response = await fetch(endpoint, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    url: 'https://example.com',
    options: { fullPage: true, type: 'png' }
  })
});

if (!response.ok) {
  throw new Error(`Screenshot request failed: ${response.status} ${await response.text()}`);
}
await Bun.write('landing-page.png', response);

The Node.js example uses Bun.write to save the response. With Node.js alone, import writeFile from node:fs/promises and write Buffer.from(await response.arrayBuffer()).

Alternative library: Playwright also provides page screenshots, including full-page capture. It is another browser-library option if your team already uses its automation workflow; the evidence here does not establish a general winner between Playwright and Puppeteer.

4. Make competitor captures repeatable

Capture settings can change what an image records. Use the same procedure for each competitor and each audit round, and keep enough metadata to interpret differences later.

  1. Set the viewport. Record width, height, and device scale factor. Keep them constant across pages in the same comparison.
  2. Choose the scope. Record whether the image is a viewport, full-page, selector, or clip capture.
  3. Define page state. Note any clicks, dismissed overlays, scrolling, or other interactions. If the audit measures the initial visitor experience, do not silently dismiss elements.
  4. Choose a wait condition. Wait for the relevant selector or state. A fixed delay can help with known delayed rendering, but it does not prove the page is stable.
  5. Handle lazy content deliberately. Browserless recommends scrolling before full-page capture when lazy loading needs to be triggered. ScreenshotOne also documents viewport, rendering, scrolling, animation, and wait controls; its guidance says higher rendering quality can reduce performance.
  6. Fix output settings. Use the same image format and quality when pixel-level comparisons matter.
  7. Save metadata. Store the requested URL, capture date and time, viewport, scope, wait condition, relevant page state, tool/API version or configuration, and output filename alongside the image.
  8. Repeat and inspect outliers. Dynamic content, experiments, personalization, and changing page data can produce different images even with identical capture settings.

These are workflow recommendations inferred from the documented controls; they are not guarantees of identical output across changing sites.

5. Puppeteer and hosted APIs compared

Dimension Puppeteer or another browser library Hosted screenshot API
Interaction You write the browser interaction and capture logic. A basic endpoint takes a URL and options; Browserless also documents a browser connection for interaction before capture.
Scope Full page, clip, and element screenshots are documented. Browserless documents full-page and selector capture.
Output control Screenshot options include image type and quality. Browserless documents image format and Puppeteer-style options.
Browser operations Your program launches and closes the browser in the documented workflow. The service exposes a managed HTTP endpoint; verify limits and operational guarantees with the provider.
Best fit Custom interactions, conditional logic, and browser-level control. Repeatable URL-based capture where the available endpoint options cover the audit.

Choose based on interaction requirements, page-state control, capture scope, and who will operate the browser. The documentation reviewed does not support ranking these approaches on price or reliability.

6. Troubleshooting

Symptom Likely cause Fix
Screenshot is blank or mostly empty Capture ran before the relevant content rendered, navigation failed, or the page requires interaction. Check navigation and response errors, wait for a meaningful selector, and reproduce required interactions before capture.
Full-page image omits lazy-loaded sections Content loads only when the page is scrolled. Scroll through the page before capture, then wait for newly requested content to render. Browserless specifically recommends scrolling to trigger lazy loading.
Navigation times out The site keeps network requests open or the chosen navigation condition is too strict for that page. Use a condition aligned with the audit, then wait for the target element or a controlled delay. Preserve timeouts so stalled captures do not hang indefinitely.
Element screenshot fails The selector does not match, is ambiguous, or the element is not yet present. Wait for the selector, confirm it resolves to the intended element, and fail clearly if it is missing.
Images differ between audit runs Viewport, page state, timing, animation, lazy content, or dynamic site data differs. Record and standardize capture settings and state. Where the API supports them, use its wait, scrolling, or animation controls.
API request returns an error Provider-specific authentication, endpoint, payload, quota, or request-size issue. Check the provider’s current API docs and error response; verify endpoint, credentials, JSON schema, URL encoding, and account limits.
Saved file is not a readable image The response body contains an error document or the request returned a non-success status. Check HTTP status and response content type before writing the body as an image; log the provider error safely.

7. Performance, reliability, and cost

Performance: Puppeteer makes browser work part of your program, so the calling environment must launch and run the browser. An API moves the request to a managed endpoint. The sources do not provide comparable latency measurements. ScreenshotOne documents that higher rendering quality can reduce performance, so tune waits and rendering controls to the quality the audit actually needs.

Reliability: A screenshot can vary because page content is dynamic or state was not reproduced consistently. For either approach, use explicit settings, bounded timeouts, clear failure handling, and metadata. The sources do not establish comparative uptime or reliability guarantees for the approaches or services.

Cost: Compare your own browser runtime and maintenance costs with the actual API plan, quotas, and request rules available to you. The research dossier does not contain comparable pricing, so it cannot support a claim that either approach is cheaper.

8. Or skip the browser setup

If a URL-based capture is enough, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; the parameter names used by other screenshot APIs also work. See the ScreenshotNeo API documentation for its options.

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 known cookie and consent banners, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the page verdict and billing status in headers. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

9. Frequently asked questions

Is Puppeteer itself a screenshot API?

No. Puppeteer is a browser automation library that your program uses to control a browser and capture images. A hosted screenshot API accepts capture work over HTTP.

Can I use Playwright instead?

Yes. Playwright also documents page screenshots, including full-page screenshots. Choose the library that fits your existing browser automation workflow and required interactions.

Only if the audit question calls for the post-dismissal page. If you are comparing the initial visitor experience, record the page as presented and make the state part of the capture metadata.

Does this evidence show which approach is more accurate or reliable?

No. The sources establish documented features, not independently measured comparative accuracy, cost, latency, or uptime.

Sources