Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesUse Playwright’s Python API to launch a browser, open a page, and call page.screenshot(). The synchronous version is the shortest path to a working image; set full_page=True for the complete scrollable document or call a locator’s screenshot() method for one element. Install both the Python package and Playwright’s browser binaries before running any script.
Install Playwright and its browsers
Playwright supports Python 3.8 or newer according to its installation documentation; check the current requirements for your operating system before deployment. In a virtual environment, run:
python -m pip install playwright
playwright install
On Linux, a targeted install can also add Chromium and its operating-system dependencies:
playwright install --with-deps chromium
The first command installs the Python bindings. The second downloads the browser engines. If you skip the browser install, a script can fail before it creates a page.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
The minimal synchronous screenshot script
This complete example launches Chromium headlessly, navigates to a URL, writes a PNG, and closes the browser even though the page is created inside a managed Playwright context.
from playwright.sync_api import sync_playwright
URL = "https://example.com"
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto(URL)
page.screenshot(path="screenshot.png")
browser.close()
Save it as screenshot.py and run python screenshot.py. The default is headless mode, so no browser window appears. The resulting screenshot.png is the visible viewport, not necessarily the entire page.
Capture the full page or one element
Full scrollable document
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={"width": 1440, "height": 900})
page.goto("https://example.com", wait_until="networkidle")
page.screenshot(path="full-page.png", full_page=True)
browser.close()
full_page=True captures the page as if it were displayed on a screen tall enough to contain the complete scrollable document. The viewport width still affects responsive layout, so choose it deliberately.
One element
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page()
page.goto("https://example.com")
page.locator(".header").screenshot(path="header.png")
browser.close()
A locator screenshot waits for the matching element and captures its bounding box. Prefer a stable selector such as a test ID or semantic role when classes are generated dynamically.
Use the async API in asyncio applications
If your service already has an asyncio event loop (for example, an async web handler or worker), use async_playwright instead of blocking the loop with the synchronous API.
Rank #2
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch()
page = await browser.new_page()
await page.goto("https://example.com")
await page.screenshot(path="screenshot.png")
await browser.close()
asyncio.run(main())
Do not call asyncio.run() from code that is already running an event loop; await main() from that application instead. Both APIs expose the same browser engines and screenshot controls.
Make captures deterministic
A screenshot is only useful when the page has reached the state you intend to record. Navigation waits for the document’s load event by default, but modern pages may render data, fonts, or images later.
- Wait for a state: use
page.goto(url, wait_until="networkidle")when a quiet network is a reasonable signal, or wait for a specific element withpage.locator(".report").wait_for(). - Wait a known delay:
page.wait_for_timeout(1000)can accommodate a short animation, but a selector-based wait is usually less brittle. - Control motion: disable CSS transitions or inject a style sheet when animation changes the pixels between runs. Playwright’s screenshot API can also control animation handling in supported versions.
- Mask changing or sensitive areas: pass locators through the screenshot API’s
maskoption so timestamps, avatars, or personal data do not create unstable diffs. - Set the environment: choose a fixed viewport, device scale factor, locale, timezone, color scheme, and user agent when visual comparisons must be reproducible.
Never treat a fixed sleep as proof that a request has completed. Wait for the application’s actual ready signal where possible.
Screenshot options you will use most
| Option | What it controls | Typical use |
|---|---|---|
path |
Writes the image to a file. | Artifacts in a test or build. |
full_page |
Captures the complete scrollable document. | Long-page documentation or audits. |
clip |
Captures a rectangular region with x, y, width, and height. |
A fixed area that is not a single element. |
type |
Selects png, jpeg, or (in current supported releases) webp. |
PNG for lossless diffs; JPEG/WebP for smaller files. |
quality |
Controls lossy image quality. | Use with JPEG or WebP; it is not applicable to PNG. |
omit_background |
Requests a transparent background where supported. | Compositing an isolated page or component. |
scale |
Controls whether output follows CSS or device pixels. | Keep dimensions consistent across retina and standard displays. |
mask |
Covers selected locators in the output. | Hide volatile or private regions. |
Screenshot methods return image bytes when path is omitted. That is useful for an upload, an in-memory transformation, or a pixel-diff pipeline:
image_bytes = page.screenshot(type="png")
with open("screenshot.png", "wb") as f:
f.write(image_bytes)
Check the API supported by the Playwright version installed in your environment before relying on a newer option. WebP output was added to page.screenshot() and locator.screenshot() in Playwright 1.62.
Choose a browser and context deliberately
Playwright can drive Chromium, Firefox, and WebKit. Select the engine that matches the compatibility question: Chromium for a Chromium-based production flow, Firefox for Gecko behavior, or WebKit for Safari-like rendering. You can launch headed mode while diagnosing layout or authentication problems:
browser = p.chromium.launch(headless=False, slow_mo=200)
Close the browser in a finally block when your script has multiple failure paths. For repeated captures, reuse one browser process and create separate contexts or pages rather than launching a new process for every URL.
Recommended Free Tools
Authentication, headers, and dynamic pages
Create a context with the conditions your site expects:
context = browser.new_context(
viewport={"width": 1440, "height": 900},
color_scheme="dark",
locale="en-US",
timezone_id="America/New_York",
extra_http_headers={"Authorization": "Bearer TOKEN"},
)
page = context.new_page()
For a logged-in flow, establish the session with the UI or load a previously saved storage state. Keep credentials out of source control. If content is loaded only after scrolling, scroll or wait for the relevant locator before taking a full-page image; otherwise lazy images may remain absent.
Troubleshooting common failures
“Executable doesn’t exist” or browser launch failure
Run playwright install (or the targeted --with-deps chromium command on Linux) in the same environment that runs Python. Containers also need the system libraries required by the selected engine.
The image is blank or incomplete
Confirm the URL is reachable from the execution host, wait for a page-specific selector, and inspect the page in headed mode. A network-idle wait can hang on applications with persistent connections; replace it with a deterministic selector wait.
The locator screenshot times out
The selector may match nothing, be hidden, or be inside a frame. Verify it with page.locator("selector").count(), wait for visibility, and use frame_locator() for an iframe.
Fonts or images differ between runs
Use a fixed browser engine, viewport, scale, locale, and timezone. Wait for the intended fonts and images, disable animation, and mask timestamps or other changing content.
Full-page output has surprising dimensions
Responsive breakpoints depend on viewport width, while device scale affects pixel dimensions. Set both explicitly and remember that very long documents can consume substantial memory.
Navigation errors, bot checks, or consent overlays
Inspect the response and page content instead of assuming the screenshot represents the target. Supply required cookies, headers, or authentication only when you are authorized to access the page. A consent dialog or chat widget can obscure the result; close it through an explicit, tested locator before capture.
Best Value
Performance, reliability, and cost considerations
- Launching a browser is expensive compared with taking another page screenshot; keep a browser alive for batches and isolate jobs with contexts.
- Full-page images and high device scales increase memory and file size. Use a viewport clip or a lower scale when a complete document is unnecessary.
- Set realistic navigation and assertion timeouts, record the failing URL, and retain a diagnostic screenshot or trace for retries.
- Retries should be bounded. Repeating a page with a permanent 404, authentication failure, or bot challenge only increases latency.
- Run untrusted URLs in an appropriately isolated environment. Restrict credentials, network access, and filesystem permissions according to your threat model.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server for developers. It removes cookie/consent banners, newsletter popups, and chat widgets before capture; bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—let Claude, Cursor, or another MCP client request captures without custom browser code.
One GET request is enough:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for all options, including full-page and element captures, device presets, custom CSS and JavaScript, waits, headers, cookies, geolocation, caching, signed links, asynchronous webhooks, bulk requests, and PDF output.
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}`);
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account.
FAQ
Does Playwright save screenshots as bytes or only files?
Both. Supplying path writes a file; omitting it returns bytes that your Python code can upload or process.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Can I capture a PDF with page.screenshot()?
No. Screenshots produce raster images. Use Playwright’s PDF capabilities for PDF output in supported Chromium workflows, or use a dedicated capture API such as ScreenshotNeo’s capture_pdf tool.
Which engine should a visual regression suite use?
Use the engine that represents the browser behavior you need to protect, and keep that choice fixed for comparable baselines. Add other engines only when cross-engine rendering is part of the requirement.
Frequently Asked Questions
Does Playwright save screenshots as bytes or only files?
Both. Supplying path writes a file; omitting it returns bytes that your Python code can upload or process.
Can I capture a PDF with page.screenshot()?
No. Screenshots produce raster images. Use Playwright’s PDF capabilities for PDF output in supported Chromium workflows, or use a dedicated capture API such as ScreenshotNeo’s capture_pdf tool.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallWhich engine should a visual regression suite use?
Use the engine that represents the browser behavior you need to protect, and keep that choice fixed for comparable baselines. Add other engines only when cross-engine rendering is part of the requirement.
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.

