Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteTo save HTML as a PNG in Python, render it in a real browser and take a screenshot. Playwright is a straightforward choice: its Python API can capture the visible viewport, the full scrollable page, or a single element, and it can return PNG bytes instead of writing directly to a file.
Use Playwright to render HTML and save a PNG
A browser engine is important because HTML may rely on CSS, fonts, images, and JavaScript to look as intended. Playwright launches Chromium, loads the page, then saves the rendered result with page.screenshot().
Install Playwright and its browser
Install the Python package and Chromium in the environment where the script will run:
python -m pip install playwrightpython -m playwright install chromium
Save the following as save_html_png.py. It captures a webpage at a fixed viewport and writes a full-page PNG:
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
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="page.png", full_page=True)
browser.close()
Run it with python save_html_png.py. The browser needs to be installed and available in that runtime; if this is a server or container, install Chromium there too. The viewport sets the browser’s visible width and height in CSS pixels. With full_page=True, Playwright captures the full scrollable document rather than only that visible area.
Capture a local HTML file
For a file on disk, convert its resolved path to a file: URL. This avoids problems caused by passing a relative path:
from pathlib import Path
from playwright.sync_api import sync_playwright
html_file = Path("page.html").resolve()
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={"width": 1440, "height": 900})
page.goto(html_file.as_uri())
page.screenshot(path="page.png", full_page=True)
browser.close()
Relative resources referenced by the HTML, such as images or stylesheets, must also be available at the locations the page expects. If the page fetches remote resources, the runtime needs network access to those resources.
Choose what part of the page to capture
| Goal | Playwright call | What it captures |
|---|---|---|
| Visible browser area | page.screenshot(path="viewport.png") |
The current viewport, using the page’s configured viewport dimensions. |
| Entire document | page.screenshot(path="full.png", full_page=True) |
The full scrollable page, including content below the fold. |
| One element | page.locator(".invoice").screenshot(path="invoice.png") |
The selected element, useful for a card, invoice, chart, or other component. |
| Image bytes in memory | png_bytes = page.screenshot() |
Image bytes that can be written to a file or passed to another image-processing step. |
For an element capture, choose a selector that identifies the intended element. If the selector matches nothing, the capture cannot be made; if it matches multiple items, make the target unambiguous. Playwright also supports animations="disabled" on screenshot calls, which can make captures more repeatable when page animations would otherwise change what appears in the image.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Write returned bytes to a file
Omit path when you want the screenshot bytes in Python. Then save, upload, or transform them as needed:
Rank #2
from pathlib import Path
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")
png_bytes = page.screenshot(full_page=True)
Path("page.png").write_bytes(png_bytes)
browser.close()
When you do provide a path, Playwright infers the screenshot type from the filename extension. A .png path selects PNG output. The API also supports JPEG and WebP; PNG is lossless, so Playwright’s screenshot quality setting does not apply to PNG captures.
Wait for the right page state before capturing
A screenshot records what the browser has rendered at capture time. A page can reach its initial load state before a particular image, chart, or client-rendered component is ready. Wait for the thing the image depends on rather than adding an arbitrary sleep.
Wait for a required element
If a known element signals that the page is ready, wait for it before taking the screenshot:
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated 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 matchpage.goto("https://example.com/report")
page.locator(".report-ready").wait_for()
page.screenshot(path="report.png", full_page=True)
Replace .report-ready with a selector that exists only when the content you need is ready. For pages whose state is better represented by a specific change, wait for that state instead.
Choose a navigation wait condition deliberately
The example uses wait_until="networkidle". This can be convenient for pages that become quiet after loading, but it is not a universal readiness test: analytics, polling, or other ongoing network activity may prevent a page from becoming idle. If that happens, navigate without relying on network idle and wait for the relevant selector or state. Conversely, if the page’s important content loads after navigation, a screenshot taken immediately can be incomplete.
Use Selenium if it is already your project standard
Selenium’s Python WebDriver can save the current window as a PNG or return its PNG bytes. It is a reasonable fit when your project already uses Selenium for browser automation:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
driver.save_screenshot("page.png")
finally:
driver.quit()
driver.save_screenshot("page.png") saves the current window, and driver.get_screenshot_as_file("page.png") is another file-saving method. To handle the PNG in memory, use driver.get_screenshot_as_png(). Selenium’s documented core screenshot methods focus on the current window and PNG files or bytes. For a direct full-page option and locator-based element screenshot, Playwright exposes full_page=True and locator screenshots in its page API.
Recommended Free Tools
Make captures consistent and manageable
- Set the viewport explicitly. Layouts can change at different widths, so use the same viewport for captures that need to be comparable.
- Wait for the actual content. Use a selector or page state tied to the material that must appear; fixed delays can be too short on a slow run and unnecessarily long on a fast one.
- Make fonts and network resources available. Missing fonts, stylesheets, or images can alter the rendered result even when the screenshot call succeeds.
- Consider the output dimensions. A full-page capture of a long document can produce a very tall image. Capture a specific element or separate sections if a single document-sized PNG is impractical for the next step.
- Control animation where appropriate. Disabling animations can reduce variation in element captures, though it does not replace waiting for data or other content to load.
These are practical implementation considerations, not performance benchmarks. Runtime and output size depend on the page, browser environment, resources, and capture dimensions; no general timing or file-size figure applies to every page.
Or skip the browser setup
If you would rather call a screenshot service than install and manage a browser, ScreenshotNeo accepts a URL and returns a screenshot as PNG, JPEG, or WebP, or a PDF. Here is the one-request cURL example; see the ScreenshotNeo API documentation for its request options:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo’s cleanup options accept cookie or consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. An MCP server offers take_screenshot, get_page_info, and capture_pdf tools for AI agents and other MCP clients. 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.
Sign up for ScreenshotNeo’s free plan to get 1,000 screenshots a month without a card.
Troubleshooting
Playwright reports that Chromium is missing
The Python package and browser runtime are separate pieces. Install Chromium in the same environment that runs the script with python -m playwright install chromium. In a deployment, container, or virtual environment, make sure the install step runs there too.
The PNG is blank or missing part of the page
Check that the target URL or local file loaded and that the content exists before capture. Wait for a selector that marks the required content as ready. For a page that keeps network connections open, do not rely solely on networkidle; use a content-specific wait instead.
Images or fonts are absent
Verify that linked resources can be reached from the browser environment and that local relative paths resolve from the HTML file’s location. A screenshot only reflects what the browser could load and render.
The output includes only the top of the page
The default screenshot is the viewport. Add full_page=True for the complete scrollable document, or take a locator screenshot if only a particular component is required.
An element screenshot fails or targets the wrong item
Confirm that the locator matches the intended element and that it is present and visible before capture. Use a more specific CSS selector when a page contains several elements with the same class.
Best Value
Selenium does not produce a complete long-page image
Selenium’s core screenshot methods capture the current window. If you need a documented direct full-page call, use Playwright’s full_page=True; otherwise, full-page behavior with Selenium may require browser-specific techniques or stitching.
Which Python approach should you choose?
For a new script that needs a viewport, full-page, or element PNG, start with Playwright’s Python API. Choose Selenium when WebDriver is already established in your project and a current-window screenshot is sufficient. In either case, render the HTML in the browser engine, wait for the content that matters, and pick the capture scope that matches the image you need.
Frequently Asked Questions
Can Playwright return a screenshot without creating a file?
Yes. Call page.screenshot() without a path to receive image bytes, then write or pass those bytes to another part of your Python program.
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 →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Can I save the screenshot as JPEG or WebP instead of PNG?
Yes. Playwright supports PNG, JPEG, and WebP; when saving to a path, the filename extension determines the output type.
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.

