Competitor tracking, client reports, visual QA after a deploy, a directory that needs a thumbnail for every listing: they all start with "take a screenshot of each of these URLs". The annoying part is never the screenshot. It is the cookie banner covering half of every image.
Short answer
Use a screenshot tool that dismisses consent banners before it captures. Capturewren (an Apify Actor) clicks away OneTrust, Cookiebot, Didomi, Quantcast, TrustArc, Usercentrics, CookieYes and plain "Accept all" buttons in 10+ languages, then captures the first screen or the full page, and returns the page title, H1, meta description and visible text with each image. $0.003 per screenshot; failed pages are free.
Step by step
- Put your URLs in a list (hundreds are fine).
- Choose
device(desktop or mobile),fullPagetrue or false, andformat(png or jpeg). - Keep
dismissCookieBannerson (the default). - Run it. Each dataset row has
screenshotUrl, the HTTP status, title, H1 and text; the images are also in the run's key-value store in input order. - Optional: add
selector(for example#pricing) to capture one element instead of the page.
Real output
| URL | HTTP | Title | H1 |
|---|---|---|---|
| stripe.com | 200 | Stripe | Financial Infrastructure to Grow Your Revenue | Financial infrastructure to grow your revenue... |
| supabase.com | 200 | Supabase | The Postgres Development Platform | Build in a weekend |
| linear.app | 200 | Linear - The system for product development | The product development |
Source: Capturewren (Apify Actor cybermax/website-screenshot) README, real run on 23 Sep 2026 (desktop, JPEG, first screen).
Python: screenshots plus page text in one loop
import os
from apify_client import ApifyClient # pip install apify-client
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("cybermax/website-screenshot").call(run_input={"urls": ["https://stripe.com", "https://linear.app"], "device": "desktop", "fullPage": True, "format": "jpeg"})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
print(row["httpStatus"], row["title"], row.get("screenshotUrl"))
curl
curl -s -X POST "https://api.apify.com/v2/acts/cybermax~website-screenshot/run-sync-get-dataset-items" \
-H "Authorization: Bearer $APIFY_TOKEN" -H "Content-Type: application/json" \
-d '{"urls": ["https://supabase.com"], "device": "mobile", "format": "png"}'
No code
n8n: an HTTP Request node posting the same JSON to the run-sync URL above, then a "Google Drive: Upload" or "Slack: Send" node per item using screenshotUrl. Make and Zapier have an Apify app with "Run an Actor" and "Get Dataset Items".
From an AI agent: Any MCP client (Claude, Cursor, VS Code) can call it through Apify's hosted MCP server: add https://mcp.apify.com/?tools=cybermax/website-screenshot with your Apify token as a Bearer header, and the agent sees one tool, cybermax--website-screenshot, with the input fields above.
Watch pages for visual changes
Turn on monitor and put the run on an Apify Schedule (daily, weekly). Unchanged pages are free, so you pay only when a competitor's homepage, pricing page or banner actually changes.
Good to know
- Price: $0.003 per screenshot ($3 per 1,000), no start fee, no subscription. Pages that fail to load are not charged.
- 404 and 500 pages are still captured with their status, because that is often exactly what you want to see.
-
includeText: true(default) gives you up to 4,000 characters of visible text per page, handy for search or an LLM summary next to the image.
FAQ
Does it work on pages that need a login? No. It captures public pages only.
Full page or first screen? First screen is faster and better for thumbnails; full page (capped by maxFullPageHeight) is better for audits.
Why not run Puppeteer myself? For ten URLs, do. For hundreds, the consent-banner handling, retries and storage are the part that eats the afternoon.
Try it on your own list: Capturewren pricing, sample output and a one-click run. Apify's free plan includes $5 of usage a month, so a first run costs nothing.
Published automatically by CyberMax. Every number above comes from the linked public data; nothing is estimated.
Top comments (0)