ScreenshotNeo

BlogHow-to

Can Puppeteer Save a Screenshot of an Article Behind a Metered Paywall?

Puppeteer can capture what an article page renders for your session, including an excerpt or paywall. It cannot reveal article text the site has not delivered.

By the ScreenshotNeo team4 October 20267 min read

Yes. Puppeteer can save a screenshot of the article page state available to the browser session. If the publisher renders the full article for your session, the screenshot can include it. If the page renders only an excerpt, a meter notice, or a paywall overlay, Puppeteer captures that visible result; a screenshot call does not unlock text the site has not delivered.

This is a distinction between capturing rendered content and accessing content. Puppeteer documents page and element screenshots, including full-page capture, but those capabilities do not grant access beyond what the current session can see. Publisher behavior varies, and the documentation does not establish how every meter works. Puppeteer’s screenshot guide and its ScreenshotOptions API describe the capture controls.

Capture only content available to your session

Navigate to the article using a browser session that already has the access you are entitled to use. Wait for the page state you want to record, then take a viewport or full-page screenshot. The screenshot reflects what that session rendered at capture time; it does not establish that the publisher made the entire article available.

The following example uses Puppeteer’s browser download and launch flow. It saves a viewport image as article.png. Run it with Node.js in a project directory:

npm install puppeteer
// save-article.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 900 });
    await page.goto('https://example.com/article', {
      waitUntil: 'networkidle2',
      timeout: 60000,
    });

    await page.screenshot({ path: 'article.png' });
    console.log('Saved article.png');
  } finally {
    await browser.close();
  }
})();

Replace the example URL with an article you are authorized to view. Save the code as save-article.js, then run node save-article.js. Puppeteer’s Page.screenshot() is the documented capture method.

Choose viewport, full-page, or element capture

Use the smallest capture that meets the need. The default screenshot records the current viewport. Set fullPage: true to capture the full page height Puppeteer can render. To capture one page element, locate it and call ElementHandle.screenshot(). These options change the area captured; they do not change what the page is allowed to show.

Full-page screenshot

await page.screenshot({
  path: 'article-full.png',
  fullPage: true,
});

Full-page capture may produce a tall image. Pages that load content as you scroll can require additional readiness handling; the screenshot option alone does not guarantee that every lazy-loaded section has been populated.

Screenshot one element

const article = await page.$('article');
if (!article) {
  throw new Error('No article element found');
}
await article.screenshot({ path: 'article-element.png' });

Change article to a selector that matches the content you intend to capture. If the page has rendered a paywall notice inside the article region, the element screenshot can include that notice. Selecting a different element does not reveal content omitted from the session.

Readiness and session considerations

There is no universal wait condition for article pages. A network-idle condition can be a reasonable starting point, but some pages keep requests open or load content after the initial navigation. When you know a visible element that signals the page is ready, wait for that selector instead:

await page.goto('https://example.com/article', {
  waitUntil: 'domcontentloaded',
  timeout: 60000,
});
await page.waitForSelector('article', { timeout: 15000 });
await page.screenshot({ path: 'article.png', fullPage: true });

Use a selector that is meaningful for the specific site. A loaded article container can still contain only an excerpt or a paywall prompt. Do not interpret a successful screenshot as proof that all article text was available.

If you already have legitimate access that depends on a signed-in browser session, use that session in accordance with the publisher’s rules and your organization’s policies. Session setup is site-specific; Puppeteer’s generic screenshot API does not define publisher authentication or metering behavior.

What Puppeteer can and cannot tell you

Page state for the browser session What the screenshot can show
The publisher renders the full article The rendered article, subject to readiness and capture-area settings
The publisher renders an excerpt and a meter prompt The excerpt and prompt visible at capture time
The publisher renders a blank or incomplete page That blank or incomplete rendered state
Content has not been delivered to the session The screenshot API cannot supply that missing content

This table describes the practical consequence of capturing the current rendered page. It is not a claim about how any particular publisher implements a meter.

Errors and troubleshooting

Symptom Likely cause What to try
TimeoutError during navigation The page did not reach the requested navigation condition before the timeout, or it keeps network activity open. Try domcontentloaded and then wait for a page-specific selector. Increase the timeout only when a slower load is expected.
Screenshot is blank or incomplete The page had not rendered the desired state, or the content is not available to the session. Wait for a meaningful selector and inspect the rendered page state. If the publisher shows a meter or excerpt, the capture cannot make withheld text appear.
Full-page image omits lower content Content may load only after scrolling or another page interaction. Use the site’s normal page interaction and wait for content to render before capturing. Do not assume fullPage triggers every site’s lazy-loading logic.
article selector is missing The page uses a different structure, has not rendered yet, or returned a different state. Wait for a site-specific selector and handle the missing element explicitly.
Navigation succeeds but the screenshot shows a paywall The browser session received a paywall state, or the full article is not available to it. Capture the visible state if that is your intended record. Use an authorized access path for the article; a screenshot option is not an access mechanism.
Browser fails to launch The Puppeteer package or its browser installation may be unavailable in the environment. Install Puppeteer in the project and follow its official setup guidance for your runtime and operating system.

Performance, reliability, and cost

  • Performance: Viewport screenshots generally involve less image output than full-page captures. Full-page images can be tall and use more memory, especially on long pages. Choose dimensions and capture area according to the output you need.
  • Reliability: Page readiness is site-dependent. Prefer a meaningful selector over an arbitrary fixed delay where possible, and close the browser in a finally block so it is closed after success or failure.
  • Cost: Puppeteer is browser automation software you run in your own environment. The cited screenshot documentation does not establish hosting, compute, or operating costs; those depend on where and how you run it.
  • Rights and retention: Technical ability to save an image does not settle whether retaining or sharing it complies with the publisher’s terms or applicable law. Check the rules that apply to your use.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call API returns a screenshot as PNG, JPEG, or WebP, or a PDF. Like Puppeteer, it captures what the page makes available to the request; it does not grant access to article text a publisher has withheld.

For an article page you are authorized to capture, this cURL request saves a WebP image. See the ScreenshotNeo API documentation for request options.

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

Equivalent Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com/article"},
    timeout=90,
)
r.raise_for_status()
with open("article.webp", "wb") as image:
    image.write(r.content)

Equivalent Node.js using built-in fetch:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com/article',
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('article.webp', Buffer.from(await res.arrayBuffer()));

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 of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. These options simplify screenshot delivery, but they do not bypass a publisher’s access controls.

Sign up for 1,000 free screenshots a month with no card.

FAQ

Does Puppeteer screenshot the full article?

Only when the full article is rendered for the browser session and the capture includes that content. A full-page screenshot does not unlock a metered article.

Will the screenshot show the paywall or the article?

It shows the page state rendered at capture time. That may be an article, an excerpt with a paywall notice, or another state.

Can a screenshot prove that I had access to the article?

No. It records pixels from a browser page; it does not establish what access was authorized or what a publisher delivered outside that captured view.

Is it permitted to keep or share the screenshot?

That depends on the applicable publisher terms, circumstances, and law. General screenshot API documentation cannot resolve that question.