Apify Website Screenshot Actor vs Playwright: Which Should You Choose?
Compare Apify’s community screenshot Actor with Playwright for setup, control, access, storage, testing, and cost. Choose the right workflow for your screenshots.
Short answer: Choose the hosted Apify Website Screenshot and PDF Actor (reestri/web-screenshot) when you want to submit public URLs, configure a managed batch, and retrieve image or PDF files without maintaining a browser script. Choose Playwright when you need browser actions, application-specific setup, screenshot assertions, or visual regression inside a test suite.
These tools work at different levels: the Apify listing is a particular community-maintained capture task; Playwright is browser automation software with a testing framework. For a managed screenshot API alternative to try first, ScreenshotNeo returns a capture from one GET request, removes supported consent banners, popups, and chat widgets before capture, and bills only clean shots.
1. What exactly are you comparing?
“Apify Website Screenshot Actor” is not a unique product name. This article compares Playwright with the Apify Store listing named Website Screenshot and PDF, maintained by the community. Its stated features and limits apply to that Actor listing, not to every Apify Actor. Check its live Store page and Input tab before relying on a particular option or price.
Apify describes Actors as cloud programs that accept structured input, perform a task, and optionally produce structured output. They can generally be run manually, through API or CLI, or on a schedule; check the individual Actor and account configuration for the exact available controls. See the Apify Actors documentation and Apify getting-started guide.
Playwright controls browser automation from code. Playwright Test adds test fixtures, assertions, and screenshot snapshots, so a capture can be part of a repeatable quality check rather than simply a file-producing job.
2. Which should you choose?
| Need | Apify Website Screenshot and PDF | Playwright |
|---|---|---|
| Setup and coding | Provide structured input to a hosted Actor; little or no browser code is needed for its standard capture workflow. | Write and maintain code that launches a browser, loads pages, configures capture, and handles output. |
| Control and customization | Use the capture options exposed by this listing: formats, viewport, waits, dark mode, CSS hiding, and related settings. | Control browser setup and actions in code, subject to browser and site behavior. |
| Batching and scheduling | Accepts batches of public URLs; Apify supports manual, API/CLI, and scheduled Actor runs in general. This listing states up to 1,000 URLs per run. | Build batching, retries, scheduling, and orchestration into your script or CI system. |
| Authenticated access | Not suitable for logged-in pages: the listing describes anonymous public-page capture and says it does not log in or bypass CAPTCHA or bot protection. | You can code an authorized login or session workflow, where the site permits automation, and manage credentials securely. |
| Result storage and export | Per-URL records and files are stored in the run’s default key-value store; records include status and capture details. | Choose where to write screenshots and how to publish, retain, or inspect them. |
| Repeatable screenshot testing | Can make captures, but the researched listing does not provide Playwright Test’s screenshot assertion workflow. | Playwright Test supports screenshot baselines and visual comparison with toHaveScreenshot(). |
| Operating cost | The listing displays per-capture rates and an Actor start event; storage and the Apify plan may also matter. Rates can change. | Playwright itself is software; account for your compute, CI, engineering, and maintenance costs. |
Choose the Actor for a quick managed run over public pages, especially when a form or structured input and stored output suit the job. Choose Playwright when page interaction, test assertions, or source-controlled visual baselines are central. A team can also use a managed batch for archive or monitoring work and Playwright for application quality gates; that is an architectural choice, not a claim of a tested integration.
3. What the Apify screenshot Actor can capture
The listing accepts a list of public URLs and supports PNG, JPEG, WebP, or PDF output. It describes viewport, full-page, and first-matching CSS-element captures. Its options include desktop, laptop, tablet, and mobile presets; custom viewport dimensions; dark-mode emulation; wait conditions; optional scrolling to load lazy content; CSS hiding; and hiding consent banners with CSS. CSS hiding does not click a consent choice or change the site’s consent state.
The listing names these presets:
- Desktop: 1920 × 1080
- Laptop: 1366 × 768
- Tablet: 800 × 1280 at 2×
- Mobile: 412 × 915 at 2.625×
Run output includes per-URL records and files in the run’s default key-value store. The record fields listed include status, requested and final URL, HTTP status, file link, dimensions, capture duration, and error details, with a run-level summary stored too. Use the records to identify which URLs failed instead of treating a partially successful batch as wholly successful.
4. Run the Apify Actor from the API
The following Python example starts the named Actor with a structured input containing two public URLs. It uses the Apify API’s synchronous run-and-get-dataset-items endpoint; replace the token placeholder with an API token and adjust the input to match the Actor’s current Input tab. The response contains dataset items, while screenshot files are in the run’s key-value store, so follow the resulting run metadata to retrieve file records and links.
import requests
APIFY_TOKEN = "YOUR_APIFY_TOKEN"
ACTOR_ID = "reestri~web-screenshot"
endpoint = f"https://api.apify.com/v2/acts/{ACTOR_ID}/run-sync-get-dataset-items"
actor_input = {
"urls": ["https://example.com", "https://www.python.org"],
"screenshotType": "fullPage",
"outputFormat": "png"
}
response = requests.post(
endpoint,
params={"token": APIFY_TOKEN},
json=actor_input,
timeout=300,
)
response.raise_for_status()
for item in response.json():
print(item)
Actor input property names can change. Confirm the exact schema and accepted values in the live listing before running this example; set the capture type and output format using the names shown there. For long runs or workflows that need run metadata and file-store access, start the Actor through the standard run endpoint, retain its run ID, then read the run’s dataset and key-value store through the Apify API. Consult the Apify API reference.
5. Capture and compare screenshots with Playwright
Install Playwright Test and its browser binaries, then create a test that navigates to the target and compares a screenshot against a committed baseline. The first run creates the baseline; inspect it and commit it with the test. Later runs compare current output with that reference.
npm init playwright@latest
npx playwright install
Save this as tests/homepage.spec.js:
const { test, expect } = require('@playwright/test');
test('homepage visual snapshot', async ({ page }) => {
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await expect(page).toHaveScreenshot('homepage.png', {
fullPage: true,
animations: 'disabled',
maxDiffPixels: 100,
});
});
Run it with npx playwright test. To deliberately refresh a reviewed baseline, run npx playwright test --update-snapshots, inspect the changed files, and commit the accepted snapshots. Do not update snapshots automatically just to silence a failure: that can turn a real visual regression into a new expected result.
toHaveScreenshot() takes repeated screenshots until two consecutive captures match, then saves the last one as the baseline. Use its options to tune comparison for your page. maxDiffPixels permits a pixel-difference count; Playwright also supports threshold-based pixel comparison options. A stylePath stylesheet can hide or normalize volatile elements such as timestamps before capture. See the official Playwright visual comparisons guide for the current assertion options and configuration.
For a plain capture without a visual assertion, await page.screenshot({ path: 'page.png', fullPage: true }) writes an image. An element capture uses await page.locator('.product-card').screenshot({ path: 'card.png' }). Add page interactions before the capture when the screenshot needs a specific state. For example, click a tab, wait for its content, then take the screenshot.
6. Can Playwright compare screenshots reliably?
Yes. Playwright Test supports visual baselines and comparison through await expect(page).toHaveScreenshot(). It is useful for catching unintended visual changes when the rendering environment and page state are controlled. Snapshot files belong with the tests and should be reviewed like other code changes.
Playwright’s documentation warns: “Browser rendering can vary based on the host OS, version, settings, hardware, power source (battery vs. power adapter), headless mode, and other factors.” It recommends using the same environment in which the baseline was generated for consistent screenshot testing. In practice, run comparisons in a stable CI image with pinned browser dependencies, fonts, viewport, locale, and relevant test data. Avoid promising identical pixels across arbitrary developer machines.
7. Can the Apify Actor capture full pages or pages requiring login?
Full-page captures
Yes. The listing supports full-page captures and optional scrolling to trigger lazy-loaded content. Its default maximum full-page height is listed as 15,000 pixels and is configurable; captures taller than the configured cap are marked truncated. WebP has a 16,383-pixel per-side limit, which can make very tall captures shorter. These are limits stated by this particular listing; verify the current Input tab before depending on them.
Login, consent, CAPTCHA, and bot checks
The listing says it captures what an anonymous visitor sees. It does not log in, accept cookies, solve CAPTCHAs, rotate proxies, or change identity to get past bot protection. It rejects URLs containing credentials, localhost, private networks, and non-web schemes. A site that blocks automation may return an error or a block page. Do not use it for private dashboards or to bypass access controls.
Playwright lets you code an authorized browser workflow, including a login session when you have permission and the site allows it. Store credentials outside source control, limit their access, and do not treat browser automation as a way around a site’s access controls.
8. Cost, capacity, performance, and reliability
Apify listing prices and run limits
As shown on the listing accessed October 3, 2026, the Actor displays a starting rate of $2.00 per 1,000 screenshots. Its pricing tab lists $0.002 for a viewport or element screenshot, $0.004 for a full-page image, $0.004 per PDF, and a $0.002 default Actor start event at 2 GB. The listing example for 1,000 viewport screenshots in one run totals $2.002. These are rates for this listing, not a general Apify tariff or a guaranteed future price.
The listing says failed URLs are not charged in specified cases, and stored files count toward Apify storage; unnamed run storage is subject to plan retention. Check the current listing and your Apify plan for capture charges, storage, retention, and run costs before estimating a job.
It states a maximum of 1,000 public URLs per run, default concurrency of two (configurable up to five), and a default full-page height cap of 15,000 pixels. Higher concurrency may reduce elapsed time for batches, but can increase simultaneous browser and target-site load; begin conservatively and respect the target sites. The listing says dropped connections and browser crashes are retried once by default, while timeouts are not retried. Split very large inputs into manageable runs and inspect per-URL statuses and errors.
Playwright operating costs
Playwright is software, so there is no screenshot-per-call price established by the cited documentation. Budget the machines or CI minutes that run browsers, storage for snapshots and artifacts, and engineering time to maintain the script and test environment. Parallel workers can shorten a suite but consume more compute and may increase load on the pages under test.
Keeping captures useful
- Use the smallest viewport and format that meet the task; full-page images and PDFs can consume more storage and capture time than viewport shots.
- Wait for a meaningful selector or known page-ready condition when possible. A fixed delay can waste time or still be too short.
- For lazy content, trigger scrolling or wait for the target section before capture.
- Keep screenshot tests deterministic: stabilize data, animations, fonts, locale, viewport, and rendering environment.
- Track per-URL failures and retry only transient errors according to the tool’s behavior; do not assume timeouts are retried by the Actor.
9. Troubleshooting common problems
| Symptom | Likely cause | What to do |
|---|---|---|
| Actor rejects an input field | The JSON field name or value differs from the current Actor schema. | Copy the current schema from the listing’s Input tab and validate a one-URL run first. |
| Actor returns a block page or error | The site blocks automation, requires identity, or is outside the listing’s supported public URL rules. | Check the URL and record error; use an authorized workflow for pages you control. The Actor does not solve CAPTCHA or evade bot controls. |
| Capture is blank or incomplete | The page had not rendered the target content, lazy content was not triggered, or a wait condition was unsuitable. | Wait for a target selector or suitable page condition, enable scrolling where appropriate, and inspect the final URL and status fields. |
| Full-page image is truncated | The configured height cap was reached, or the output format’s dimensions limit was reached. | Check the listing’s current height setting and format limits; use a different format or capture sections separately where appropriate. |
| Actor run is slow or only partly succeeds | Large pages, a big batch, slow sites, or low concurrency can extend the run; some failures are URL-specific. | Review per-URL durations and error details, reduce the batch to isolate slow URLs, and tune concurrency within the listing’s stated limit. |
| Playwright screenshot assertion fails everywhere | The baseline and current run may use different OS, browser, fonts, headless mode, or page data. | Run in the baseline environment, stabilize inputs, and review the diff before updating snapshots. |
| Playwright diff has small noisy changes | Animations, timestamps, rotating content, or antialiasing create pixel variation. | Disable animations, hide or normalize volatile regions with a stylesheet, and adjust a documented tolerance only when the visual difference is acceptable. |
| Playwright page times out waiting for network idle | Long polling or background requests can keep the network active. | Wait for a specific selector or application-ready signal instead of requiring network idle. |
| Baseline update hides a real defect | Snapshots were regenerated without reviewing the image diff. | Restore the baseline, inspect the intended UI change, then update and commit only reviewed snapshots. |
10. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF. Its supported clean-shot flow accepts cookie/consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, with response headers identifying the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, or any MCP client.
For example, request a screenshot 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,
)
open("shot.webp", "wb").write(r.content)
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(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
See the ScreenshotNeo API documentation for the 63 capture options, including full-page and CSS-element shots, device and viewport settings, PDF output, custom CSS or JavaScript, cookies and headers, waits, caching, signed links, async jobs, and bulk captures of up to 100 URLs per call. 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month, with no card required.
11. Frequently asked questions
Is the Apify Website Screenshot and PDF Actor built by Apify?
The researched reestri/web-screenshot listing is community-maintained. Do not assume its behavior or limits apply to other Actors.
Can I use the Actor for a recurring screenshot job?
Apify supports scheduled Actor runs generally. Confirm that the schedule and API workflow you need are available for your account and configure the specific Actor’s input and output handling.
Should I commit Playwright screenshot baselines?
Yes, when they are the reviewed reference for your tests. Keep them with the test code so changes can be reviewed together.
Which option is best for a one-off public-page capture?
The Actor is a reasonable hosted choice when its input and output suit the job. A screenshot API such as ScreenshotNeo is another low-setup option when a single request fits better.
12. Final recommendation
Use the community Apify Actor for low-code batches of anonymous public pages when its capture options and stored run output fit. Use Playwright when screenshots are part of a controlled browser workflow or visual regression test. For a one-call API that removes supported consent banners, popups, and chat widgets and reports which captures are billable, try ScreenshotNeo first. Start with its API documentation or create a free account for 1,000 screenshots per month with no card.
