ScreenshotNeo

BlogHow-to

How to Capture Paywalled Pages with Chrome Remote Debugging and a Signed-In Profile

Capture a page you can access with your subscription using Chrome DevTools Protocol. Set up an isolated signed-in profile, save a screenshot or PDF, and protect the session.

By the ScreenshotNeo team4 October 20269 min read

If you can already read a page through your subscription, Chrome DevTools Protocol (CDP) can capture its rendered view as a screenshot or print it to PDF. Use a dedicated Chrome profile, sign in through the publisher’s normal login flow, and connect only trusted local software to the debugging port. This workflow does not bypass a paywall or grant access you do not have.

Since Chrome 136, remote debugging switches require a non-default user data directory. Chrome made this change so debugging does not target the everyday Chrome profile. See the Chrome security announcement and the CDP screenshot and PDF commands.

Before you capture a page

  1. Confirm you have legitimate access to the page. Check the publisher’s terms for printing, downloading, and automated access.
  2. Decide whether you need a visual image or a document. A screenshot preserves a rendered frame; a PDF is better suited to page-oriented reading and printing. Layout and completeness depend on the site.
  3. Use a dedicated profile directory and keep the debugging endpoint available only to trusted local tools. Do not use your everyday profile or leave unrelated sensitive tabs open.
  4. Store the resulting file as confidential. Access to a subscription does not automatically settle whether making or sharing a copy is permitted.

Start Chrome with a dedicated debugging profile

Close other Chrome windows first if you might confuse which instance a tool controls. Choose a new, non-default directory that you control. The following examples use port 9222 and keep the debugging listener on loopback.

macOS

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/chrome-paywall-profile"

Linux

google-chrome \
  --remote-debugging-port=9222 \
  --user-data-dir="$HOME/chrome-paywall-profile"

Windows PowerShell

& "${env:ProgramFiles}\Google\Chrome\Application\chrome.exe" `
  --remote-debugging-port=9222 `
  --user-data-dir="$env:LOCALAPPDATA\ChromePaywallProfile"

If Chrome is installed in a different location, adjust the executable path. Keep the profile directory separate from Chrome’s normal data directory. With Chrome 136 and later, the remote-debugging switches are not honored against the default data directory.

Sign in and open the page

  1. In the newly opened Chrome window, visit the publisher’s website and sign in through its ordinary login page.
  2. Open the specific page you are authorized to access. Resolve any sign-in prompt or consent step manually.
  3. Wait for the article and its visible assets to finish rendering. Scroll through the page if needed to trigger lazy-loaded images, then return to the desired capture position.
  4. Do not export, copy, or transmit session cookies. CDP can act on the already-authenticated browser without manually handling cookie values.

Capture a screenshot or PDF with Node.js

This example uses Playwright Core to connect to the Chrome instance through CDP. It captures the current tab and does not handle login credentials or cookies. Install Node.js, then install the dependency:

npm install playwright-core

Save as capture.cjs. Pass the exact target URL as the first argument; the script checks that the connected tab matches it before saving. Set OUTPUT to pdf for a PDF.

const { chromium } = require('playwright-core');

async function main() {
  const targetUrl = process.argv[2];
  if (!targetUrl) throw new Error('Usage: node capture.cjs <authorized-page-url>');

  const browser = await chromium.connectOverCDP('http://127.0.0.1:9222');
  try {
    const contexts = browser.contexts();
    const pages = contexts.flatMap(context => context.pages());
    const page = pages.find(candidate => candidate.url() === targetUrl);
    if (!page) {
      throw new Error('Open the exact target URL in the signed-in debugging Chrome first.');
    }

    await page.bringToFront();
    await page.waitForLoadState('domcontentloaded');
    // Optional: allow client-side rendering to settle. Choose a site-appropriate delay.
    await page.waitForTimeout(1500);

    if (process.env.OUTPUT === 'pdf') {
      await page.pdf({ path: 'page.pdf', printBackground: true });
      console.log('Saved page.pdf');
    } else {
      await page.screenshot({ path: 'page.png', fullPage: true });
      console.log('Saved page.png');
    }
  } finally {
    // Disconnect this client; do not close the user's Chrome instance here.
    await browser.close();
  }
}

main().catch(error => {
  console.error(error.message);
  process.exitCode = 1;
});

Run it with the page URL quoted so shell characters are not interpreted:

node capture.cjs 'https://publisher.example/article'
OUTPUT=pdf node capture.cjs 'https://publisher.example/article'

On PowerShell, use $env:OUTPUT="pdf"; node capture.cjs "https://publisher.example/article" for PDF output. The URL is a placeholder: substitute the page you are authorized to capture. The script prints the page currently rendered by Chrome; a long page can produce a large image. If you need a particular viewport rather than the entire page, replace fullPage: true with fullPage: false.

Screenshot or PDF: choose the output

Output Use it when Check afterward
Screenshot You need to preserve the visible visual presentation or a particular state. For full-page captures, check that the whole article rendered and that lazy images loaded. Very tall pages may be unwieldy.
PDF You need page-oriented reading, printing, or a document file. Review page breaks, headers, figures, and print styles. The result may differ from the browser view.

The relevant CDP methods are Page.captureScreenshot and Page.printToPDF. This guide’s Playwright example wraps browser control; CDP behavior and site rendering can vary. See the Page domain protocol documentation for protocol details.

Protect the signed-in session and output

  • Treat the debugging port as browser control. A process that can connect may control the browser. Chrome’s DevTools MCP documentation warns that applications on the machine can connect to an enabled debugging port. Keep it local, run only trusted software, and close the debugging browser when finished.
  • Assume the profile contains sensitive data. A connected agent may access open tabs and data exposed through browser APIs, including cookies and storage. A dedicated profile reduces exposure to your everyday profile but still holds an authenticated session. See Chrome’s remote debugging guidance.
  • Protect files and logs. Store the capture securely and limit access. If you export a HAR for a separate debugging task, use sanitized export unless sensitive headers are specifically necessary. Chrome’s Network panel documentation explains that sanitized HAR export omits sensitive headers such as Cookie, Set-Cookie, and Authorization by default; another export option includes sensitive data.
  • Close Chrome after capture. This ends the debugging session and reduces the time the authenticated profile is exposed to connected software.

Permission and sharing considerations

Use this method only for pages you are authorized to access, and follow the publisher’s terms for automated access, printing, retention, and sharing. A subscription by itself does not determine whether retaining or redistributing a full copy is allowed.

For U.S. copyright questions, the Copyright Office explains that fair use depends on the circumstances; there is no fixed number of words or percentage that automatically qualifies. The statutory factors include purpose and character, nature of the work, amount and substantiality, and effect on the potential market. See the U.S. Copyright Office fair use page and 17 U.S.C. § 107. This general information does not decide whether a particular capture is lawful. Check applicable terms and local law before sharing or publishing a capture.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. For a page your account is authorized to access, a single API request can return an image or PDF. It does not sign in to subscriber accounts or bypass paywalls; use it only with pages accessible under your authorization and the publisher’s rules. The API parameter names used by other screenshot APIs also work, which can make switching straightforward. See the ScreenshotNeo API documentation.

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,
)
r.raise_for_status()
with open("shot.webp", "wb") as image:
    image.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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Replace the example URL with a page you are permitted to capture. Cookie banners, popups, and chat widgets are removed before the shot, and each of those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers report 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 without a card; paid plans start at $5 for 3,000. Every feature is on every plan. Sign up free for 1,000 screenshots a month, no card required.

Troubleshooting

Symptom Likely cause Fix
Chrome ignores --remote-debugging-port Chrome 136 or later is using the default profile directory. Launch with --user-data-dir set to a new, non-default directory. Confirm you are connecting to the instance launched with that directory.
The page asks you to subscribe or sign in The dedicated profile has its own session and does not inherit the everyday profile’s login. Sign in normally in the dedicated Chrome window and open the page there. Do not copy cookies between profiles.
Connection refused on port 9222 Chrome was not launched with the debugging flag, exited, or is listening on a different port. Check the launch command and that the dedicated Chrome process remains open; make the port in the client URL match the launch flag.
Script cannot find the page The target URL differs from the open tab, perhaps due to a redirect, trailing slash, or query string. Pass the exact current URL from the address bar, or change the script to select the intended tab explicitly after inspecting open tab URLs locally.
Screenshot is blank or incomplete The page may still be rendering, need scrolling to load lazy images, or be blocked by site behavior. Wait for the article to render, scroll through it, return to the capture position, then capture again. Follow publisher restrictions; do not attempt to evade access controls.
PDF has missing figures or awkward page breaks The site’s print stylesheet or layout handles print differently from the screen. Inspect the PDF and compare against the rendered page. Try a screenshot when visual fidelity is essential, or use the publisher’s supported download/print feature.
Large or failed full-page capture A very tall page can require substantial memory or contain content that never finishes loading. Use a viewport screenshot or PDF, allow lazy content to load, and retry only after checking that the page is stable. Split the task only if the publisher permits it.

Performance, reliability, and cost

With local CDP, capture work runs in the Chrome process and machine you launch. Page size, images, scripts, rendering delays, and full-page dimensions affect completion time and output size. Full-page screenshots can use more memory than viewport captures. Wait for the content you need, but avoid treating a fixed delay as proof that every resource loaded.

Reliability depends on the publisher’s login session, page rendering, network, and print styles. A login may expire or a site may restrict automation. Confirm the saved file opens and contains the intended page. Reuse the dedicated profile only while needed, keep its permissions limited, and close it after capture.

The Chrome/CDP workflow has no ScreenshotNeo API charge, but it uses local compute and requires profile setup and maintenance. ScreenshotNeo offers 1,000 captures monthly free with no card; listed paid tiers are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free. Only clean shots are billed, and the response identifies billing status. See the docs for request parameters and options.

FAQ

Does remote debugging get around a paywall?

No. This procedure assumes you can already view the page through an authorized session. It does not defeat a paywall or create subscription access.

Will my regular Chrome login appear in the new profile?

No. A separate user data directory is a separate profile. Sign in through the publisher’s normal flow in that profile if permitted.

Can I share the PDF because I pay for access?

A subscription does not by itself answer that. Publisher terms and applicable law govern, and fair use is circumstance-specific. Check before sharing.

Can I use this method with any publisher?

Technical behavior varies by login system, rendering, and publisher restrictions. This guide does not validate any particular site; follow that publisher’s terms.