Recommended Free Tools
The dependable way to take website screenshots automatically is to run a browser in a script: open the URL, wait for the page state you need, and save a screenshot. Playwright and Puppeteer provide the most control; Chrome Headless is the quickest command-line option. Run that script from a scheduler or CI job for weekly or other recurring captures.
Choose the capture method first
Your choice depends on whether the page needs interaction, how much control you need, and whether the job will run repeatedly.
| Method | Best fit | Control and output |
|---|---|---|
| Playwright | Automated workflows that may use Chromium, Firefox or WebKit | Browser contexts, waits, full-page screenshots, clipping and image options |
| Puppeteer | JavaScript automation centered on Chromium pages | Full-page, clipped or transparent captures, output path, image type and quality settings |
| Chrome Headless | A simple URL-to-image command | --screenshot, window sizing and timeout flags without writing a program |
A viewport screenshot contains the visible browser area. A full-page screenshot extends below the fold. Element or clipped captures are useful when you need only a chart, product card or other region.
Automate screenshots with Playwright
Install and create a script
Install Playwright in a new Node.js project, then install its browser binaries:
#1 Best Overall
mkdir site-captures
cd site-captures
npm init -y
npm install playwright
npx playwright install chromium
Create capture.mjs. This example fixes the viewport, waits for a meaningful selector, and writes a full-page PNG.
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 1
});
try {
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 60_000
});
await page.locator('main').waitFor({ state: 'visible', timeout: 30_000 });
await page.screenshot({
path: 'example-full.png',
fullPage: true,
type: 'png'
});
} finally {
await browser.close();
}
Replace https://example.com and main with the page and selector that define “ready” for your site. A navigation event only proves that navigation reached its selected state; it does not prove that a client-rendered chart, table or image has appeared.
Viewport, element and image options
- For only the visible viewport, omit
fullPageor set it tofalse. - For one element, obtain its bounding box and pass a
cliprectangle, or use a locator’s bounding box before callingscreenshot. - Use
type: 'jpeg'or'webp'when supported by your installed Playwright version; usequalityfor lossy formats. Quality does not apply to PNG. - Set
deviceScaleFactorto 2 for a retina-style image, but keep it unchanged when comparing runs.
Wait for asynchronous content
Prefer a condition tied to the content you need:
await page.goto('https://example.com/dashboard', { waitUntil: 'domcontentloaded' });
await page.locator('[data-testid="sales-chart"]').waitFor({ state: 'visible' });
await page.screenshot({ path: 'dashboard.png', fullPage: true });
If no stable selector exists, a short, documented delay can be a fallback. Do not treat a fixed delay as proof that every network request or animation has finished.
Automate screenshots with Puppeteer
Install and run
mkdir puppeteer-capture
cd puppeteer-capture
npm init -y
npm install puppeteer
Save this as capture.mjs:
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
try {
await page.goto('https://example.com', {
waitUntil: 'domcontentloaded',
timeout: 60_000
});
await page.waitForSelector('main', { visible: true, timeout: 30_000 });
await page.screenshot({
path: 'example-full.png',
fullPage: true,
type: 'png'
});
} finally {
await browser.close();
}
Clip an element or change format
const box = await page.locator('.pricing-card').boundingBox();
if (!box) throw new Error('pricing card is not visible');
await page.screenshot({ path: 'card.jpeg', clip: box, type: 'jpeg', quality: 85 });
Puppeteer also supports an output path, transparent backgrounds and image settings. A quality value has no effect on PNG output.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Use Chrome Headless from the command line
For a straightforward capture, run Chrome with its headless screenshot flag. Set the viewport explicitly so repeated files have a predictable size:
Rank #2
google-chrome --headless --disable-gpu
--window-size=1440,900
--screenshot=example.png
https://example.com
Some installations use chromium or chromium-browser instead of google-chrome. A timeout flag can limit how long Chrome waits before proceeding, but it cannot tell you that a particular dynamic element is ready. For pages that need selectors, clicks or authentication, use Playwright or Puppeteer.
Make captures recurring
The browser script or Chrome command performs one capture. A separate scheduler must invoke it. Keep the schedule, naming convention and retention policy explicit.
Example: cron on Linux
0 9 * * 1 cd /opt/site-captures && /usr/bin/node capture.mjs >> capture.log 2>&1
This runs at 09:00 every Monday in the machine’s local time. Use an absolute working directory and executable path, and redirect logs so failures are visible. A CI scheduler can run the same command; configure its artifact storage and secret handling separately.
File names and retention
Include the capture date in each filename, such as home-2026-09-29.png. Decide how many historical files to retain and remove older files only after a successful new capture. If the page requires a login, treat the resulting images and cookies as sensitive data.
Make visual comparisons reliable
Keep the browser engine and version, operating system, viewport, device scale factor, fonts, color scheme, timezone and headless mode consistent. Playwright notes that screenshots can vary with operating system, browser version, settings, hardware, power source and headless mode. A changed environment can create pixel differences even when the page has not materially changed.
Rank #3
- Use a fixed viewport for every run.
- Wait for the same selector or application state.
- Disable or hide animated elements when your workflow permits it.
- Record the URL, timestamp, browser version and options beside each image.
- Review differences caused by ads, rotating content, timestamps and personalized data before treating them as regressions.
Common failures and fixes
Blank or partially rendered image
Cause: the screenshot ran before client-side content was ready, or the selected wait state was too weak. Fix: wait for the specific heading, table, chart or image selector; increase the navigation timeout only when the site genuinely needs more time.
Selector timeout
Cause: the selector is wrong, appears only after a click, is inside an iframe, or is hidden at the chosen viewport. Fix: verify the selector in browser developer tools, wait for the frame when applicable, perform the required interaction, and capture diagnostic HTML or a smaller viewport while debugging.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Infinite or unexpectedly tall pages
Cause: full-page capture measures the document, while infinite-scroll pages may keep adding content. Fix: implement the site’s scroll-and-load sequence explicitly, or capture a defined viewport or element. Full-page support alone does not guarantee that every lazy-loaded or infinite-scroll element is included.
Different pixels on each run
Cause: changed browser or OS settings, fonts, animation, ads, time-dependent content or device scale. Fix: pin the environment and viewport, wait for stable content, and remove known dynamic sources where possible.
Chrome command fails
Cause: the executable name or flag differs by installation and version. Fix: locate the installed Chromium/Chrome binary, check its current headless help output, and use an absolute path in automation.
Rank #4
Authentication or private data leaks
Cause: a scheduled job captured a logged-in page and stored it where others can read it. Fix: use a dedicated account with minimum access, protect cookies and artifacts, restrict storage permissions, and define deletion rules.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP or PDF. Before capture it accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether it was billed.
Here is the cURL call (see the ScreenshotNeo documentation for all options):
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Equivalent 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)
Equivalent 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 fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
Options for production workflows
- Full-page, element-by-CSS-selector, dark mode, 12 device presets or any viewport, retina scale and transparent backgrounds.
- PDF paper size, margins, landscape mode and page ranges.
- Custom CSS and JavaScript, pre-capture clicks, selector hiding, waits for a selector, delay or network idle.
- Blocking for ads, trackers, requests or resource types; custom headers, cookies, user agent and Authorization; timezone and geolocation.
- Image resizing, a chosen cache TTL, signed links for public
<img>tags, 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 simplify migration.
An MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients, so an AI agent can request captures without you wiring a browser runtime.
Pricing
| Plan | Included shots | Price |
|---|---|---|
| Free | 1,000 per month | $0, no card |
| Starter | 3,000 | $5 |
| Growth | 15,000 | $15 |
| Pro | 60,000 | $39 |
| Scale | 250,000 | $99 |
| Business | 1,000,000 | $249 |
Yearly billing gives two months free, and every feature is included on every plan. Start with 1,000 free screenshots a month without a card.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
FAQ
Can a screenshot make page text accessible to automation?
No. It records rendered pixels; it does not provide semantic text or controls for downstream automation. Use page inspection or an accessibility-oriented workflow when those are required.
Best Value
Should I use a viewport or full-page image?
Use a viewport image for what a visitor sees immediately. Use full-page when the deliverable must include content below the fold, provided the page has a bounded document.
Is a scheduler included in Playwright or Puppeteer?
No. Those libraries capture when invoked. Cron, CI scheduling or another external runner must start the command.
Frequently Asked Questions
Can a screenshot make page text accessible to automation?
No. It records rendered pixels; it does not provide semantic text or controls for downstream automation. Use page inspection or an accessibility-oriented workflow when those are required.
Should I use a viewport or full-page image?
Use a viewport image for what a visitor sees immediately. Use full-page when the deliverable must include content below the fold, provided the page has a bounded document.
Is a scheduler included in Playwright or Puppeteer?
No. Those libraries capture when invoked. Cron, CI scheduling or another external runner must start the command.
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.




