How to take website screenshots with Python

Three approaches, with code you can copy and run.

March 27, 2026 · 8 min read

Need to capture a screenshot of a web page from Python? You have three main options: run a headless browser locally with Playwright or Selenium, or call a screenshot API. Each has different trade-offs around setup complexity, reliability, and cost.

Option 1: Playwright (local browser)

Playwright is the modern choice for browser automation. It's maintained by Microsoft, supports Chromium, Firefox, and WebKit, and has excellent Python bindings.

Install
pip install playwright
playwright install chromium
Python
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="screenshot.png", full_page=False)
    browser.close()

Pros: Full control, no per-screenshot cost, works offline.
Cons: You manage Chromium installation, updates, memory, and crash recovery. Doesn't work in serverless environments (Lambda, Vercel). The playwright install step downloads ~400MB of browser binaries.

Option 2: Selenium (local browser)

The older approach. Selenium has been around since 2004 and works with every major browser via WebDriver.

Install
pip install selenium webdriver-manager
Python
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager

options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1440,900")

driver = webdriver.Chrome(
    service=Service(ChromeDriverManager().install()),
    options=options,
)
driver.get("https://example.com")
driver.save_screenshot("screenshot.png")
driver.quit()

Pros: Mature ecosystem, lots of documentation and StackOverflow answers.
Cons: ChromeDriver version management is a persistent headache. Slower than Playwright. API is more verbose. Same operational overhead as Playwright regarding browser management.

Option 3: Screenshot API

Offload the browser entirely. Send an HTTP request, get an image back. No browser to install, no processes to manage.

Python
import requests

response = requests.post(
    "https://api.nightglass.xyz/api/v1/screenshot",
    headers={
        "Content-Type": "application/json",
        "Authorization": "Bearer YOUR_API_KEY",
    },
    json={
        "url": "https://example.com",
        "width": 1440,
        "height": 900,
    },
)

with open("screenshot.png", "wb") as f:
    f.write(response.content)

Pros: No browser management, works in any environment (serverless, containers, CI), consistent rendering, sub-3-second response times.
Cons: Costs money (nightglass: $0.005/screenshot), requires network access, you're depending on an external service.

Which should you use?

The decision comes down to volume, environment, and how much operational overhead you want to take on.

Use Playwright if you need full browser automation (clicking, filling forms, navigating multi-page flows) and you control the server environment. It's the best local option by a wide margin.

Use a screenshot API if you just need URL-to-image conversion, you're running in serverless/constrained environments, or you don't want to manage headless browser infrastructure. At half a cent per screenshot, it's cheaper than your time debugging Chromium crashes.

Avoid Selenium for new projects unless you have a specific reason (e.g., existing Selenium test suite you want to reuse). Playwright does everything Selenium does, but better.

For a deeper look at headless browser tradeoffs generally, see the complete headless browser guide. If you're on serverless, headless browsers won't work there. Comparing APIs? The 2026 comparison covers the main players.