Website Screenshot Generator - Full Page PNG and JPEG
Pricing
from $3.00 / 1,000 screenshot takens
Website Screenshot Generator - Full Page PNG and JPEG
Take screenshots of a list of website URLs. You get a PNG or JPEG of each page. Pick full page or viewport, width 320-2560 px, 1x/2x/3x density, dark mode, mobile layout. A CSS selector hides the cookie banner. One row per page: image link, final URL, title, status.
Pricing
from $3.00 / 1,000 screenshot takens
Rating
0.0
(0)
Developer
Dami's Studio
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Website Screenshot Generator: a picture of every page in your list, PNG or JPEG
Paste a list of addresses and you get an image of each page, plus a row carrying the link to that image, the final URL after redirects, the page title, the HTTP status, the dimensions and the file size.
You control what the camera sees: the first screen or the whole page stitched together, any width from 320 to 2,560 pixels, normal or retina density, light or dark, desktop or phone layout. CSS selectors let you delete the cookie banner and the chat bubble before the shutter fires, or photograph one element on its own.
Worth knowing before the first run. A page that answers 404 or 500 and still renders is a real
screenshot and is charged like any other, with statusCode on the row to tell you. A page that
refuses to render at all still gets its image stored and handed to you, and that one is not charged.
| Input | Page addresses, up to 300 per run |
| Output | One row per page, with a link to its image |
| Ceiling | 300 pages per run, inside a total image size budget you set |
| Account needed | None |
| Price | $3.00 per 1,000 screenshots, which is $0.003 each, flat on every plan |
๐ธ What Website Screenshot Generator does
It opens each address in a real browser at the size you asked for, waits as long as you told it to, applies your CSS, and takes the picture. Images land in the run's key-value store and every row links straight to its own.
Full-page capture scrolls the page and stitches it into one tall image, up to the height ceiling you
set, and marks truncated when it had to cut. Scrolling also happens on request without full-page
capture, which is what makes lazy-loaded images below the fold actually appear.
The selector fields are where most of the work happens in practice. removeSelectors takes an
element out of the layout, which is the one for cookie banners and pop-ups. hideSelectors makes it
invisible but keeps its space, which is right for a sticky header you want gone without everything
shifting up. selector narrows the shot to one element.
locale and timezone are passed to the browser, so a site that localises renders in the language
and clock you asked for.
Duplicate addresses are dropped before anything renders, so a messy list does not cost twice.
๐ฅ What you give it
{"urls": ["https://example.com", "https://news.ycombinator.com"],"fullPage": true,"viewportWidth": 1440,"format": "jpeg","quality": 80,"removeSelectors": ["#cookie-banner", ".intercom-launcher"],"maxItems": 10}
| Field | Comes set to | What it is |
|---|---|---|
urls | two examples | The pages, one per line. A bare domain works. Up to 300. |
maxItems | 10 | Hard stop on how many pages this run photographs, 1 to 300. Keep it low while testing. |
fullPage | false | Off gives you exactly the viewport. On scrolls and stitches the whole page. |
viewportWidth, viewportHeight | 1440, 900 | The browser window. 390 wide is a phone, 1920 a desktop monitor. |
deviceScaleFactor | 1 | 2 is retina, 3 is print. Remember 2x is four times the file size. |
format, quality | jpeg, 80 | JPEG is much smaller. PNG is lossless and can carry transparency. Quality applies to JPEG only. |
darkMode, mobile | false | Ask the page for its dark theme, and render as a touch phone. Pair mobile with a narrow width. |
waitUntil | domcontentloaded | How ready the page must be: commit, domcontentloaded, load or networkidle. On an ad-funded page networkidle often waits for the timeout. |
delayMs | 800 | Extra pause for animations and fonts, up to 15 seconds. |
navigationTimeoutMs | 25000 | Give up on a page that has not become ready in this long. If enough of the page exists by then, it is still captured. |
scrollToBottom | false | Scroll first so lazy images load. On automatically with fullPage. |
maxFullPageHeight | 8000 | Tallest a full-page shot may be before it is cut, up to 20,000 px. |
maxTotalImageMb | 250 | The run stops once it has written this many megabytes. Pages it never reached are not charged. |
selector | empty | A CSS selector to photograph one element instead of the page. |
hideSelectors, removeSelectors | empty | Up to 30 selectors each: hide keeps the space, remove takes it out of the layout. |
customCss | empty | Raw CSS injected just before the shot, up to 4,000 characters. |
transparentBackground | false | PNG only. Leaves the page background out, for dropping an element into a design. |
locale, timezone | empty | en-US, de-DE, Europe/Berlin, America/New_York. |
concurrency | 3 | Pages rendered at once, 1 to 6. Drop to 1 for a site that objects. |
useProxy | false | Turn it on if a site refuses the run. |
proxyUrls | empty | Your own servers, as http://user:pass@host:port. Only the first entry in the list is used, and it takes precedence over everything else. |
Leave urls empty and you get one sample row showing the shape, with no browser started and
nothing charged.
๐ค What you get back
A real row from a real run:
{"ok": true,"charged": true,"recordType": "screenshot","url": "https://example.com/","screenshotUrl": "https://api.apify.com/v2/key-value-stores/zBdffYZdgUJdUcRAq/records/screenshot-001-example.com.jpg?signature=9w6b5...","screenshotKey": "screenshot-001-example.com.jpg","finalUrl": "https://example.com/","title": "Example Domain","statusCode": 200,"imageWidth": 1440,"imageHeight": 900,"format": "jpeg","fullPage": false,"darkMode": false,"deviceScaleFactor": 1,"viewportWidth": 1440,"viewportHeight": 900,"pageHeight": 900,"truncated": false,"fileSizeBytes": 17536,"loadTimeMs": 1090,"scrapedAt": "2026-09-21T01:27:34.234Z"}
| Field | What it is |
|---|---|
screenshotUrl, screenshotKey | A direct link to the image, and its name in the run's key-value store. Download what you want to keep. |
url, finalUrl | What you asked for, and where it ended up after redirects. |
statusCode | The main document's status. A page that rendered on a 404 says 404 here. |
imageWidth, imageHeight | Read from the image itself, so this is the real picture size, density included. |
pageHeight, truncated | How tall the document was, and whether the height ceiling cut it. |
fileSizeBytes, loadTimeMs | Useful for spotting the page that is quietly eating your size budget. |
format, fullPage, darkMode, deviceScaleFactor, viewportWidth, viewportHeight | The settings this shot was taken with, copied onto the row, so a mixed dataset stays readable. |
๐งพ Reading the output
recordType and ok separate the three kinds of row. charged is the flag that marks a real
screenshot apart from the sample and the diagnostics, rather than a receipt.
| Row | How to spot it | Charged |
|---|---|---|
| A screenshot | recordType is screenshot, ok is true | yes |
| The sample row | _sample is true | no |
| A diagnostic | _diagnostic is true, with an errorCode | no |
The table view has no errorCode column, so a failed row can look like a thin successful one. A
BLOCKED row even carries an image. Filter on recordType when you are counting.
| Code | What it means |
|---|---|
BLOCKED | The site would not let the page render. The image of whatever was on screen is still delivered. |
NAV_TIMEOUT | Nothing usable had loaded inside navigationTimeoutMs. |
NAV_ABORTED | Not a page the browser can display. A PDF or other file lands here. |
DNS_FAILED, CONNECTION_REFUSED, TLS_FAILED | The address did not resolve, the server refused, or the certificate did not check out. |
SELECTOR_NOT_FOUND | Your selector matched nothing on the page. |
IMAGE_TOO_LARGE | The picture went past the encoder's ceiling of 16,000 pixels a side. |
BUDGET_REACHED | maxTotalImageMb is spent. One row says so and the pages after it are skipped. |
TIME_BUDGET | The run ran out of time before reaching that page. |
RENDER_FAILED, RENDERER_CRASHED | The browser failed on that page. Worth one re-run. |
PROXY_INPUT_ADJUSTED | A network option you set was not one this actor uses, so it carried on without it. |
โถ๏ธ How to run it
- Open Website Screenshot Generator and click Try for free.
- Put your addresses into Page addresses, one per line.
- Set Maximum screenshots low for the first run, so you can check the framing before paying for 300 of them.
- Add the cookie banner and chat bubble to Remove these elements. That one change improves more screenshots than any other setting here.
- Click Start, then open the rows to see the images, or pull them from the key-value store.
๐ฐ How much does it cost?
$3.00 per 1,000 screenshots, which is $0.003 each. Flat on every Apify plan, no volume tiers.
You pay per image taken. The sample row is not charged, nor are the diagnostics: a page that was refused, timed out with nothing to show, had no matching selector, or was skipped once the size budget ran out. A page that rendered is charged whatever its status code says.
Ten screenshots is three cents. The whole 300 is ninety.
๐ก What people use it for
- Thumbnails for a directory or a link roundup, generated from the list you already have.
- Before and after shots of a redesign, same width, same settings, two runs.
- Visual regression checks on a schedule: same pages, same size, compare the images.
- Capturing one element cleanly, a pricing table or a chart, with a transparent background for a deck.
- Checking how a set of pages looks on a phone, dark mode on, without touching a device.
- Evidence and archiving, with
finalUrl,statusCodeand a timestamp on every row.
๐ง What it does not do
- Nothing behind a login. No cookies, no sign-in, no sessions.
- 300 pages per run. Split a longer list, or schedule it.
- The page is frozen once it has painted, so content that arrives very late can be missing. Raise
delayMsor useloadornetworkidlewhen that matters. - Height and size ceilings. 20,000 pixels of page by your setting, 16,000 pixels a side at the encoder, and the total megabytes you allowed.
- No PDF output. PNG and JPEG only.
- No text extraction. For the words on the page, use the crawler linked below.
- It cannot make a site render. A page that refuses gives you the image of the refusal, free.
- Only the first entry in your own server list is used.
๐งญ Which site tool do you need?
| If you want | Use |
|---|---|
| Pictures of pages | This one |
| The same pages as text, Markdown and chunks | Website Intelligence Crawler |
| Repositories and developer profiles | GitHub Scraper |
| Package metadata and download counts | npm + PyPI Package Scraper |
โ Questions people ask
How do I get rid of the cookie banner? Put its CSS selector into Remove these elements. Open the site, inspect the banner, copy the id or class.
Why is my full-page shot cut off? It hit maxFullPageHeight. The row says truncated: true.
Raise the ceiling, but remember an endless feed has no bottom.
Can I screenshot one element? Yes, with selector. Pair it with PNG and a transparent
background to drop it straight into a design.
Where do the images live? In the run's key-value store, linked from screenshotUrl on every
row. Download the ones you want to keep.
Why do two runs of the same page look different? Fonts, animations and ads settle at different
speeds. Raise delayMs, or switch waitUntil to load, and the shots get more repeatable.
Is screenshotting a public page legal? It photographs public pages as a visitor sees them. What you do with the images afterwards is subject to copyright and the site's terms. Apify's write-up on the legality of web scraping is a good starting point, and we are not lawyers.
๐ If something breaks
Open the Issues tab on the actor page. Send the address and the run ID. If a diagnostic row
landed, its errorCode and details usually name the reason already.