The most reliable way to capture screenshots from several web pages is to automate a URL list. For a handful of pages, use your browser’s built-in screenshot command. For repeated work, a Playwright script can visit each URL, wait for the right page state, capture either the visible viewport or the entire scrollable page, and save uniquely named files. A hosted API such as ScreenshotNeo removes browser setup and can process the same workflow with one request per URL.
Choose the right capture method
| Situation | Best starting point | Important decisions |
|---|---|---|
| A few pages, occasional use | Built-in browser screenshot | Whether your browser supports full-page capture, and where it saves or copies the image |
| A list of URLs or recurring jobs | Playwright script or a Playwright-based CLI | Browser engine, wait condition, viewport versus full page, filenames, retries and failure logging |
| Parallel capture from an R workflow | webshot2 | Output naming and available CPU and memory when URLs are loaded in parallel |
| JavaScript browser automation | Puppeteer | Chrome automation setup and the same navigation, waiting and output decisions |
| No local browser installation | ScreenshotNeo API | Request options, authentication, billing verdict headers and whether you need PNG, JPEG, WebP or PDF |
A viewport screenshot contains only the currently visible browser area. A full-page screenshot includes the page’s scrollable content. Decide this before writing the script: a viewport image is useful for visual regression at a fixed screen size, while a full-page image is better for documentation, audits and archiving.
Manual capture for a small number of pages
Firefox
Firefox’s screenshot feature can capture the visible area or the full web page, then save or copy the result. Open the page, use the browser screenshot command, choose the full-page option when you need all scrollable content, and save each image with a descriptive filename. The exact menu wording and placement can vary by Firefox version.
Other browsers
Chromium-based browsers commonly expose screenshot commands through developer tools or browser menus, but full-page support and save behavior vary by browser and version. If the command captures only what is visible, scroll-and-stitch manually or switch to automation. Manual capture becomes error-prone when URLs, dimensions or filenames must remain consistent.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minutePC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11#1 Best Overall
- 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
- Optical Zoom: 4x optical zoom with a 27mm wide angle lens for flexible framing indoors or outdoors
- Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
- Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
- LCD Screen and Battery: 2.7in LCD screen with 2 AA alkaline batteries for convenient on-the-go use
Automate a URL list with Playwright
Playwright provides browser pages, navigation and screenshot options for Chromium, Firefox and WebKit. The following illustrative Node.js workflow reads one URL per line, validates the list, waits for navigation, captures either a viewport or full page, sanitizes filenames and records failures without stopping the remaining work.
1. Install the runtime and browser
- Install a current Node.js release.
- Create a project:
mkdir multi-page-shots && cd multi-page-shots && npm init -y. - Install Playwright:
npm install playwright. - Download the browser binaries required by your selected engine:
npx playwright install chromium. Usefirefoxorwebkitinstead if that is the engine you need.
2. Prepare the URL list
Create urls.txt with one absolute HTTP or HTTPS URL on each line. Blank lines and lines beginning with # are ignored:
https://example.com/
https://example.org/docs
# This line is a comment
https://example.net/pricing
3. Save the capture script
const fs = require('node:fs/promises');
const path = require('node:path');
const { chromium } = require('playwright');
const input = process.argv[2] || 'urls.txt';
const outputDir = process.argv[3] || 'screenshots';
const fullPage = process.env.FULL_PAGE === '1';
const browserName = process.env.BROWSER || 'chromium';
function safeName(raw) {
return raw.replace(/^https?:\/\//, '')
.replace(/[^a-zA-Z0-9._-]+/g, '_')
.replace(/^_+|_+$/g, '')
.slice(0, 150) || 'page';
}
async function launch() {
if (browserName === 'firefox') return require('playwright').firefox.launch({ headless: true });
if (browserName === 'webkit') return require('playwright').webkit.launch({ headless: true });
return chromium.launch({ headless: true });
}
(async () => {
const lines = (await fs.readFile(input, 'utf8')).split(/\r?\n/)
.map(s => s.trim()).filter(s => s && !s.startsWith('#'));
await fs.mkdir(outputDir, { recursive: true });
const failures = [];
const browser = await launch();
const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 1 });
for (let i = 0; i < lines.length; i++) {
const url = lines[i];
let parsed;
try { parsed = new URL(url); if (!/^https?:$/.test(parsed.protocol)) throw new Error('URL must use HTTP or HTTPS'); }
catch (err) { failures.push({ url, error: err.message }); continue; }
const page = await context.newPage();
const filename = `${String(i + 1).padStart(3, '0')}-${safeName(parsed.hostname + parsed.pathname)}.png`;
try {
await page.goto(url, { waitUntil: 'networkidle', timeout: 60000 });
await page.screenshot({ path: path.join(outputDir, filename), fullPage, type: 'png' });
console.log(`saved ${filename}`);
} catch (err) {
failures.push({ url, error: err.message });
console.error(`failed ${url}: ${err.message}`);
} finally { await page.close(); }
}
await browser.close();
await fs.writeFile(path.join(outputDir, 'failures.json'), JSON.stringify(failures, null, 2));
process.exitCode = failures.length ? 1 : 0;
})();
4. Run viewport or full-page captures
node capture.js urls.txt shots
FULL_PAGE=1 node capture.js urls.txt full-page-shots
BROWSER=firefox FULL_PAGE=1 node capture.js urls.txt firefox-shots
Each page gets a numbered, sanitized name, so two URLs with similar paths remain distinguishable. The script writes failures.json even when some pages fail. A nonzero exit code makes the job visible to CI systems while still preserving successful images.
Make repeated captures consistent
Viewport, scale and browser engine
Keep the browser engine, viewport width and height, device scale factor, color scheme and locale constant when comparing captures over time. A responsive page can render a completely different layout at 390 pixels than at 1440 pixels. Use a separate output directory for each deliberate configuration.
Waiting for dynamic content
networkidle is useful for pages that finish loading network requests, but analytics, advertisements or live feeds can keep requests open indefinitely. In those cases, wait for a meaningful selector, use a bounded delay after navigation, or wait for a site-specific ready state. Lazy-loaded images may require scrolling or an application-specific trigger before a full-page image is complete.
Rank #2
- 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
- Optical Zoom: 5x optical zoom with a 28mm wide angle lens for flexible framing indoors or outdoors
- Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
- Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
- LCD Screen and Battery: 2.7in LCD screen and a rechargeable lithium-ion battery for on-the-go use
Authentication and private pages
Public URLs can be opened directly. Login-protected pages require a controlled authentication flow or a saved browser storage state. Do not place passwords or session cookies in urls.txt, source control or logs. Confirm that you have permission to capture private content.
Filename and storage strategy
Preserve enough hostname, path or an explicit page identifier to identify every image. Sanitize slashes, query characters and reserved filesystem symbols. If query parameters identify meaningful variants, hash or encode them into the filename rather than silently dropping them. Store a manifest containing the original URL, timestamp, viewport, engine and capture result alongside the images.
Command-line and other automation options
Playwright-based CLI
shot-scraper is a command-line utility built on Playwright. It can be convenient when you prefer shell scripts and configuration files over maintaining a Node.js program. You still need to decide the browser setup, full-page behavior, wait strategy and naming scheme.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Puppeteer
Puppeteer is a JavaScript library for browser automation, and screenshot generation is one of its documented uses. It is a practical alternative when your existing automation stack is built around Chrome. The same workflow applies: validate URLs, navigate, wait, capture, record failures and continue.
R and webshot2
webshot2 documents loading and screenshotting multiple supplied URLs in parallel. Parallelism can reduce elapsed time, but it also increases browser and memory consumption. Limit concurrency on small machines and use deterministic output names.
Rank #3
- Latest Digital Camera Built-in Fill Light : This compact digital camera is paired with a powerful CMOS processor and image stabilization to help you take & record the most exciting moments in 44 MP quality images & FHD 1080P quality videos anywhere, anytime. Plus, there is also a built-in fill light to help you take high quality pictures even in low light&dark settings, making this the perfect camera for all indoors/outdoors situations.
- Long-Lasting Battery Life & 16X Digital Zoom :This point and shoot camera will retain its battery charge even after long use. The controls and functions are easy to operate making this the perfect choice for children, teens and younger. This kids camera supports 16x digital zoom, you can zoom in or out the subject by pressing the W/T button for taking still photos to zoom in or out on distant objects and capture all the details you need.
- Multifunctional & Portable Digital Camera: This cheap digital camera is slim enough to fit in your pocket. You'll easily be able to take it with you on all your indoor/outdoor activities and adventures and ideal for beginners, children and teenagers. This kids digital camera is equipped with 20 filters, anti-shaking, self-timer, continuous shooting, date stamp, time-lapse recording, smile capture, internal MIC and speaker (recording sound videos), great for your daily photography needs.
- WEBCAM & PAUSE FUNCTION : More than just a FHD 1080p digital camera, it also works as a webcam for video calls and vlogging. Connect the camera to the computer, press shutter and power button at the same time and the camera will automatically turn on webcam mode for all your video calling and live streaming needs. The pause function allows you to pause when seeing playback videos.
- A Must Have Photography Device : This digital camera with SD card made from high-quality materials, this retro camera is safe and durable. Perfect for all ages to develop & improve their photographic abilities and observation skills. Our dedicated and experienced 24/7 support team is available for all after purchase troubleshooting, questions and technical help.
Or skip the browser setup: ScreenshotNeo
ScreenshotNeo is a website screenshot API and MCP server. A GET request returns a PNG, JPEG, WebP or PDF. Before capture, it accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers.
One request with cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
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()
open("shot.webp", "wb").write(r.content)
print(r.headers.get("X-Page-Verdict"), r.headers.get("X-Billed"))
Node.js
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(`${res.status} ${res.statusText}`);
const data = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', data));
console.log(res.headers.get('X-Page-Verdict'), res.headers.get('X-Billed'));
See the ScreenshotNeo documentation for parameters. The service supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, 12 device presets or any viewport, retina scale, PDF paper size and page ranges, HTML/CSS rendering, custom JavaScript and CSS, pre-capture clicks, hidden selectors, selector or delay waits, network-idle waits, ad and tracker blocking, custom headers, cookies, user agents and Authorization, timezone and geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can reduce migration effort.
ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Every feature is included on every plan: 1,000 screenshots per month free without a card; Starter is $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 provides two months free.
Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card. Cookie banners, popups and chat widgets are removed before the shot; bot checks, blank pages and failed loads are not billed; and an MCP server lets AI agents take screenshots.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Troubleshooting multi-page captures
The output is only the visible portion
Enable the tool’s full-page option. In Playwright this is fullPage: true; in a browser UI, choose the full-page command if the browser provides one.
Images or text are missing
The page may still be rendering lazy content. Wait for a known selector, scroll deliberately, use a bounded delay, or capture after the application reports readiness. Check the saved image at its native dimensions rather than relying only on a thumbnail.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsNavigation times out
Check DNS, TLS, redirects, authentication and robots or bot challenges. Increase the timeout only when the page is legitimately slow. Otherwise record the failure and continue instead of allowing one URL to block the batch.
Rank #4
- 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
- Optical Zoom: 5x optical zoom with a 28mm wide angle lens for flexible framing indoors or outdoors
- Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
- Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
- LCD Screen and Battery: 2.7in LCD screen and a rechargeable lithium-ion battery for on-the-go use
Every page looks different between runs
Fix viewport, engine, scale, locale, timezone and color scheme. Disable or mask animations where your tool permits it, wait for stable content, and avoid capturing pages with live timestamps or rotating advertisements when visual comparison matters.
Filenames overwrite one another
Include an index and sanitized hostname/path, or assign IDs in the input list. Keep the original URL in a manifest so a filename never becomes the only record of page identity.
The batch is too slow or exhausts memory
Reuse one browser process, close each page after capture and limit parallel workers. Parallel capture reduces elapsed time only when the machine and target sites can handle the added load. Respect site access policies and avoid unnecessary repeat requests by using a suitable cache strategy.
Operational checklist
- Validate every URL and confirm capture permission.
- Choose viewport or full page explicitly.
- Set a fixed viewport, browser engine and scale for repeatability.
- Define a selector, delay or network condition that means the page is ready.
- Use unique sanitized filenames and save a URL manifest.
- Record errors, status and retry decisions.
- Protect credentials, cookies and private screenshots.
- Review a sample of outputs for blank pages, consent overlays and incomplete lazy content.
Frequently asked questions
Can I screenshot a list of URLs without opening each page manually?
Yes. Feed the list to a Playwright, Puppeteer, shot-scraper, webshot2 or ScreenshotNeo workflow and save one output per URL.
What is the difference between a viewport and full-page screenshot?
A viewport image covers the browser area currently visible; a full-page image includes the page’s scrollable content.
Should I use PNG, JPEG or WebP?
PNG is generally convenient for text and pixel comparison, while JPEG and WebP can reduce file size. Choose based on whether fidelity, transparency or storage matters most.
Quick Recap
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.
Recommended Free Tools

