Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use Puppeteer’s Page.screenshot() inside a bounded Node.js queue, and pass Chromium a --proxy-server argument when it launches. Puppeteer provides the single-page capture operation; reading a URL list, limiting concurrency, naming files, and recording failures are parts of your script—not a built-in bulk API.

What you need before you start

  • Node.js and a project with Puppeteer installed. Pin the version your project uses and check that its Chromium browser launches in the environment where the batch will run. The Puppeteer overview describes the browser-launch and page-navigation model.
  • A text file containing one target URL per line.
  • A proxy endpoint compatible with the browser and the sites you intend to capture. Do not put proxy credentials in source code or logs.
  • An output directory with enough space for the expected images, particularly if you request full-page captures.

The Puppeteer screenshot guide identifies Page.screenshot() as the capture operation and demonstrates navigation, saving an image, and closing the browser: Puppeteer screenshots guide.

Install Puppeteer and prepare a URL list

In a new Node.js project, install Puppeteer and save the dependency in the project manifest:

npm install puppeteer

Create urls.txt in the project directory, with one URL on each line:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Logitech Brio 101 Full HD 1080p Webcam for Streaming and Meetings - Black
  • Compatible with Nintendo Switch 2’s new GameChat mode
  • Auto-Light Balance: RightLight boosts brightness by up to 50%, reducing shadows so you look your best—compared to previous-generation Logitech webcams (1)
  • Privacy with a Slide: The integrated webcam cover makes it easy to get total, reliable privacy when you're not on a video call
  • Built-In Mic: The built-in microphone lets others hear you clearly during video calls
  • Easy Plug-And-Play: The Brio 101 works with most video calling platforms, including Microsoft Teams, Zoom and Google Meet—no hassle; it just works
https://example.com/
https://www.iana.org/domains/reserved

Keep URLs you are authorized to access in the list. The example script below rejects malformed entries and protocols other than HTTP and HTTPS before opening a page. It uses a hash of each normalized URL for output names so that different URLs do not overwrite one another just because their paths or hostnames sanitize to the same text.

Run a bulk capture through a browser proxy

Save the following as bulk-screenshot.mjs. It uses a browser-wide proxy argument, a bounded worker pool, a per-navigation timeout, one new page per URL, explicit screenshot settings, a JSON Lines manifest, and browser cleanup in a finally block.

import puppeteer from 'puppeteer';
import { createHash } from 'node:crypto';
import { mkdir, readFile, writeFile } from 'node:fs/promises';
import path from 'node:path';

const inputFile = process.env.URLS_FILE ?? 'urls.txt';
const outputDir = process.env.OUTPUT_DIR ?? 'screenshots';
const manifestFile = path.join(outputDir, 'manifest.jsonl');
const proxyServer = process.env.PROXY_SERVER;
const concurrency = positiveInteger(process.env.CONCURRENCY, 2);
const navigationTimeoutMs = positiveInteger(process.env.NAVIGATION_TIMEOUT_MS, 30000);
const fullPage = process.env.FULL_PAGE === 'true';

function positiveInteger(value, fallback) {
  if (value === undefined || value === '') return fallback;
  const number = Number(value);
  if (!Number.isInteger(number) || number < 1) {
    throw new Error(`Expected a positive integer, received: ${value}`);
  }
  return number;
}

function parseUrls(text) {
  const urls = [];
  const invalid = [];

  for (const [index, line] of text.split(/r?n/).entries()) {
    const value = line.trim();
    if (!value || value.startsWith('#')) continue;
    try {
      const url = new URL(value);
      if (url.protocol !== 'http:' && url.protocol !== 'https:') {
        throw new Error('Only HTTP and HTTPS URLs are supported');
      }
      urls.push(url.href);
    } catch (error) {
      invalid.push({ line: index + 1, value, error: error.message });
    }
  }

  if (invalid.length) {
    throw new Error(`Invalid URL entries: ${JSON.stringify(invalid)}`);
  }
  return urls;
}

function outputName(url) {
  const parsed = new URL(url);
  const readable = `${parsed.hostname}${parsed.pathname}`
    .replace(/[^a-zA-Z0-9._-]+/g, '-')
    .replace(/^-+|-+$/g, '')
    .slice(0, 80) || 'page';
  const hash = createHash('sha256').update(url).digest('hex').slice(0, 16);
  return `${readable}-${hash}.png`;
}

const urls = parseUrls(await readFile(inputFile, 'utf8'));
await mkdir(outputDir, { recursive: true });
// Start a fresh manifest for this run.
await writeFile(manifestFile, '');

const launchArgs = [];
if (proxyServer) launchArgs.push(`--proxy-server=${proxyServer}`);

const browser = await puppeteer.launch({ args: launchArgs });
let nextIndex = 0;

async function appendManifest(record) {
  await writeFile(manifestFile, `${JSON.stringify(record)}n`, { flag: 'a' });
}

async function capture(url) {
  const outputPath = path.join(outputDir, outputName(url));
  let page;
  const record = {
    requestedUrl: url,
    outputPath,
    status: 'failed',
    navigationStatus: null,
    finalUrl: null,
    error: null
  };

  try {
    page = await browser.newPage();
    page.setDefaultNavigationTimeout(navigationTimeoutMs);
    const response = await page.goto(url, { waitUntil: 'networkidle2' });
    record.navigationStatus = response?.status() ?? null;
    record.finalUrl = page.url();

    await page.screenshot({
      path: outputPath,
      type: 'png',
      fullPage
    });
    record.status = 'success';
  } catch (error) {
    record.error = error instanceof Error ? error.message : String(error);
  } finally {
    if (page) await page.close().catch(() => {});
    await appendManifest(record);
    console.log(JSON.stringify(record));
  }
}

async function worker() {
  while (true) {
    const index = nextIndex++;
    if (index >= urls.length) return;
    await capture(urls[index]);
  }
}

try {
  await Promise.all(
    Array.from({ length: Math.min(concurrency, urls.length) }, () => worker())
  );
} finally {
  await browser.close();
}

Run it with a proxy endpoint supplied through the environment rather than embedded in the script. Replace the example endpoint with the address and port supplied by your proxy service:

PROXY_SERVER='http://proxy.example:8080' node bulk-screenshot.mjs

You can change the input file, output directory, concurrency, timeout, and capture scope without editing the script:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Logitech C270 720p Webcam Plug-and-Play Wide Screen Video Calling - Black
  • Compatible with Nintendo Switch 2’s new GameChat mode
  • Crisp HD 720p/30 fps video calls with diagonal 55° field of view and auto light correction. Compatible with popular platforms including Skype and Zoom.
  • The built-in noise-reducing mic makes sure your voice comes across clearly up to 1.5 meters away, even if you’re in busy surroundings.
  • C270’s RightLight 2 feature adjusts to lighting conditions, producing brighter, contrasted images to help you look good in all your conference calls.
  • The adjustable universal clip lets you attach the camera securely to your screen or laptop, or fold the clip and set the webcam on a shelf. You’re always ready for your next video call.
URLS_FILE='targets.txt' OUTPUT_DIR='shots' CONCURRENCY=3 NAVIGATION_TIMEOUT_MS=45000 FULL_PAGE=true PROXY_SERVER='http://proxy.example:8080' node bulk-screenshot.mjs

The defaults are a concurrency of two and a 30-second navigation timeout; these are script defaults, not Puppeteer guarantees or recommended universal limits. Set FULL_PAGE=true to capture the whole document; otherwise the image captures the page’s viewport.

What the script records

Each completed URL produces a JSON object on standard output and a line in manifest.jsonl. A record includes the requested URL, output path, success or failure, response status when navigation produced a response, final URL after redirects when available, and an error message on failure. A failed navigation does not stop the other workers. The script does not retry failures; add a small, bounded retry policy only if your targets and proxy permit it.

A response status such as 404 or 500 is recorded but does not by itself mark the capture as failed: the script can still save a screenshot of the response page. If your job should treat particular HTTP statuses as failures, add that policy explicitly after page.goto().

Configure the proxy for page traffic

Puppeteer launch options accept extra browser arguments. The script passes --proxy-server=... to Chromium at launch, following the browser-wide routing approach shown in this third-party Puppeteer proxy guide. Check the guide’s proxy examples against your chosen proxy scheme and current browser setup; authentication behavior can vary, so verify it with the exact Puppeteer, Chromium, proxy, and authentication method you will use in production.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
NexiGo N60 1080P Webcam with Microphone, Software Control & Privacy Cover, USB HD Computer Web Camera, Plug and Play, for Zoom/Skype/Teams, Conferencing and Video Calling
  • 【Full HD 1080P Webcam】Powered by a 1080p FHD two-MP CMOS, the NexiGo N60 Webcam produces exceptionally sharp and clear videos at resolutions up to 1920 x 1080 with 30fps. The 3.6mm glass lens provides a crisp image at fixed distances and is optimized between 19.6 inches to 13 feet, making it ideal for almost any indoor use.
  • 【Wide Compatibility】Works with USB 2.0/3.0, no additional drivers required. Ready to use in approximately one minute or less on any compatible device. Compatible with Mac OS X 10.7 and higher / Windows 7, 8, 10 & 11 / Android 4.0 or higher / Linux 2.6.24 / Chrome OS 29.0.1547 / Ubuntu Version 10.04 or above. Not compatible with XBOX/PS4/PS5.
  • 【Built-in Noise-Cancelling Microphone】The built-in noise-canceling microphone reduces ambient noise to enhance the sound quality of your video. Great for Zoom / Facetime / Video Calling / OBS / Twitch / Facebook / YouTube / Conferencing / Gaming / Streaming / Recording / Online School.
  • 【USB Webcam with Privacy Protection Cover】The privacy cover blocks the lens when the webcam is not in use. It's perfect to help provide security and peace of mind to anyone, from individuals to large companies. 【Note:】Please contact our support for firmware update if you have noticed any audio delays.
  • 【Wide Compatibility】Works with USB 2.0/3.0, no additional drivers required. Ready to use in approximately one minute or less on any compatible device. Compatible with Mac OS X 10.7 and higher / Windows 7, 10 & 11, Pro / Android 4.0 or higher / Linux 2.6.24 / Chrome OS 29.0.1547 / Ubuntu Version 10.04 or above. Not compatible with XBOX/PS4/PS5.

There are two separate proxy concerns:

  • Downloading or configuring Puppeteer’s browser: Puppeteer’s configuration guide discusses HTTP_PROXY, HTTPS_PROXY, and NO_PROXY as environment-only configuration settings.
  • Routing the browser’s requests to target sites: configure the browser route deliberately, for example with the launch argument used in this script. Do not assume that environment variables used to download a browser automatically route the pages Chromium loads.

The configuration guide also notes that puppeteer-core ignores Puppeteer configuration and environment variables. If you use puppeteer-core, check which settings your own launch code must supply. To confirm target-page routing, use an egress-check endpoint you are allowed to access and inspect the address observed by that endpoint.

Proxy credentials should be supplied using a mechanism supported by your proxy and browser setup, kept out of source control, and excluded from logs. Validate authentication before processing a large batch. The cited third-party guide discusses authentication, but its approach is not a universal guarantee for every proxy type or browser version.

Choose capture settings and isolation deliberately

Viewport or full page

fullPage is false by default in Puppeteer’s ScreenshotOptions. Set it to true only when the full document is needed: long pages can create much taller and larger images than a viewport capture. The API also documents element clipping and background handling; use a clip when you need a specific page region or a background option when the default treatment is unsuitable.

Image format and quality

The script requests PNG, a lossless format suitable when preserving rendered detail matters. Puppeteer’s screenshot options also include supported alternatives such as JPEG and WebP, depending on the API and browser support in use. The quality option applies to lossy formats, not PNG. Choose the format based on fidelity, file size, and whether lossy compression is acceptable; consult the option reference for current supported values.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
EMEET C960 1080P Webcam with Microphone, 2 Mics, 90° FOV, Computer Camera
  • 1080P Webcam with Cover for Video Calls - EMEET computer webcam provides design and Optimization for professional video streaming. Realistic 1920 x 1080p video, 5-layer anti-glare lens, providing smooth video. C960 computer camera delivers 1920x1080 video with fixed focus (11.8–118.1 inches), so as to provide a clearer image. C960 USB webcam has a cover and can be removed automatically to meet your needs for privacy. For optimal image performance, use the webcam in a well-lit environment.
  • Built-in 2 Omnidirectional Mics - EMEET webcam with microphone for desktop features 2 built-in omnidirectional microphones, picking up your voice to create clear audio for communication. When installing the webcam, select EMEET C960 as the default microphone input device in your computer and video applications and select C960 as the default device in Zoom/Teams and ensure microphone permissions are enabled for proper use. Please note that C960 does not include built-in speakers.
  • Automatic Light Adjustment - Automatic exposure adjustment is applied in EMEET HD webcam 1080p so that the streaming webcam can deliver stable image performance. EMEET C960 camera for computer also features color adjustment and exposure optimization to help you look your best. For optimal video quality, it is recommended to use the webcam in normal or well-lit environments and select suitable video settings in your application. Proper lighting helps achieve a clearer and more balanced image.
  • Plug-and-Play & Upgraded USB Connectivity - New C960 webcam features both USB Type-A & A-to-C adapter connections for wider compatibility. For stable performance, connect the webcam directly to the computer's main USB port and ensure the device is recognized correctly. If a hub or docking station is used, please ensure it provides sufficient power and stable data transmission, as limited ports may affect performance. 90° wide-angle lens captures more participants without frequent adjustments.
  • High Compatibility & Multi Application - C960 webcam for laptop is compatible with Windows 10/11, macOS 10.14+, and Android TV 7.0+. Not supported: Windows Hello, TVs, tablets, or game consoles. It works with Zoom, Teams, Facetime, Google Meet, YouTube and more. Please select C960 webcam as the default camera and microphone device in your application and ensure camera/microphone permissions are enabled, especially on macOS. (Tips: Incompatible with Windows Hello)

Wait behavior and timeouts

This example waits for networkidle2 before capture. That can suit pages which finish their important network activity, but pages with persistent requests may not reach that condition. For those sites, use a different explicit wait condition, wait for a meaningful selector, or wait for a deliberate short delay after navigation. Set a timeout that fits the sites and runtime rather than allowing an individual navigation to hang indefinitely. The Page screenshot and navigation APIs document the available operations: Page.screenshot API.

Session isolation

The sample opens a new page for each URL in the same browser. If the targets must share cookies or logged-in state, define and test that session behavior explicitly; if they must be isolated from one another, use separate browser contexts as appropriate. Page and context choices affect cookies and session state, so there is no one isolation policy that fits every batch.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Set concurrency, retries, and output policy

Bound the worker count

The queue starts no more workers than the number of URLs and caps active pages at CONCURRENCY. There is no universal safe concurrency value documented for Puppeteer: suitable load depends on page size, proxy capacity, target behavior, and available memory. Start conservatively, observe resource use and proxy behavior, and adjust using your own workload rather than assuming a pages-per-minute rate.

Decide which failures to retry

Navigation errors and timeouts may be transient, but repeated requests can burden target sites or violate proxy-provider limits. If retries are appropriate, cap the attempt count, record each attempt, and avoid retrying persistent HTTP error responses automatically unless that is your intended policy. The example continues after each failed URL and preserves a manifest record rather than retrying.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Sale
Logitech C920x HD Pro PC Webcam Full 1080p/30fps Video - Black
  • Compatible with Nintendo Switch 2’s new GameChat mode
  • HD lighting adjustment and autofocus: The Logitech webcam automatically fine-tunes the lighting, producing bright, razor-sharp images even in low-light settings. This makes it a great webcam for streaming and an ideal web camera for laptop use
  • Advanced capture software: Easily create and share video content with this Logitech camera that is suitable for use as a desktop computer camera or a monitor webcam
  • Stereo audio with dual mics: Capture natural sound during calls and recorded videos with this 1080p webcam, great as a video conference camera or a computer webcam
  • Full HD 1080p video calling and recording at 30 fps. You'll make a strong impression with this PC webcam that features crisp, clearly detailed, and vibrantly colored video

Keep names and manifests reliable

The filename combines a readable hostname/path fragment with a SHA-256-derived suffix. The suffix reduces collision risk between URLs whose readable portions are alike. The manifest maps each requested URL to its final URL, output path, outcome, response status, and error. For rerunnable or concurrently launched jobs, use a unique output directory per run or otherwise coordinate manifest writes; this example truncates the manifest at startup and is intended for one process per output directory.

Troubleshoot common failures

  • Chromium does not launch: confirm Puppeteer and its browser are installed for the runtime environment, and that the deployment environment permits the browser to start. Check the official installation guide for environment setup.
  • The target connects directly instead of through the proxy: verify the proxy argument is present in the launch configuration and the endpoint is valid for Chromium. Check observed egress with an allowed test endpoint; do not rely on browser-download environment settings as proof of page routing.
  • Proxy authentication fails: verify the proxy’s required scheme and authentication method against your exact browser and Puppeteer versions. Avoid printing credentials in command logs or manifests.
  • Navigation times out: check whether the URL is reachable through the proxy and whether the chosen wait condition is appropriate. Some pages keep network connections open; try a different explicit wait condition or a bounded selector/delay strategy.
  • The screenshot is blank or incomplete: confirm navigation reached the expected page and that your wait condition covers the page content you need. Some sites render important content after initial navigation or require interaction; add a target-specific wait rather than simply raising concurrency.
  • Images are missing in full-page captures: confirm the page has had time to load lazy content. Puppeteer documents full-page capture, but the example does not scroll through the document to trigger every site’s lazy-loading behavior. Add deliberate scroll-and-wait logic if the target requires it.
  • The job uses too much memory or stresses the proxy: reduce the bounded concurrency, capture the viewport instead of the full document when sufficient, and monitor the actual workload. Puppeteer documentation does not specify a universal safe worker count.
  • Output files overwrite or manifests mix runs: keep the hash suffix in output names, use a distinct output directory for each run, and do not start multiple instances that truncate or append to the same manifest without coordinating writes.

Or skip the browser setup

If you do not need a custom Puppeteer runtime, ScreenshotNeo provides a website screenshot API and MCP server. A GET request can return a PNG, JPEG, WebP, or PDF; its API accepts the parameter names other screenshot APIs use, which can make migration simpler. This one-call cURL example saves a WebP screenshot; see the ScreenshotNeo documentation for request options and setup.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
  • Cookie/consent banners are accepted and removed before capture, along with supported newsletter popups and chat widgets; each step can be turned off.
  • Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; each response identifies the page verdict and billing status in headers.
  • 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 per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

Frequently Asked Questions

Is bulk screenshotting built into Puppeteer?

No. Puppeteer documents the per-page screenshot operation; the URL queue, concurrency, filenames, and manifest in this guide are application code.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Does a proxy argument guarantee every target request uses the proxy?

No. Test egress and authentication with the exact proxy, browser, and runtime configuration you plan to use.

Quick Recap

SaleBestseller No. 1
Logitech Brio 101 Full HD 1080p Webcam for Streaming and Meetings - Black
Logitech Brio 101 Full HD 1080p Webcam for Streaming and Meetings - Black
Compatible with Nintendo Switch 2’s new GameChat mode; Built-In Mic: The built-in microphone lets others hear you clearly during video calls
$24.99
SaleBestseller No. 2
Logitech C270 720p Webcam Plug-and-Play Wide Screen Video Calling - Black
Logitech C270 720p Webcam Plug-and-Play Wide Screen Video Calling - Black
Compatible with Nintendo Switch 2’s new GameChat mode
$16.89
SaleBestseller No. 5
Logitech C920x HD Pro PC Webcam Full 1080p/30fps Video - Black
Logitech C920x HD Pro PC Webcam Full 1080p/30fps Video - Black
Compatible with Nintendo Switch 2’s new GameChat mode; Fully compatible with Windows 11
$54.99

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.