Tutorial··8 min read

How to Take Website Screenshots in Python

There are three real ways to programmatically capture website screenshots in Python. Each has a different weight class — from heavyweight browser automation to a four-line API call. Here's the code for all three, with the trade-offs laid out honestly.

1

Selenium + Chrome

Selenium is the original browser automation tool. It launches a real Chrome instance, navigates to the page, and captures the viewport. It works, but it's heavy — you need Chrome installed, a matching ChromeDriver version, and enough RAM to run a full browser.

selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1280,800")

driver = webdriver.Chrome(options=options)
driver.get("https://example.com")
driver.save_screenshot("screenshot.png")
driver.quit()

Watch out for:

  • ChromeDriver version mismatches after browser updates
  • No native full-page screenshot — viewport capture only
  • Requires pip install selenium plus a system-level Chrome install
  • Memory-heavy in CI/CD environments (2GB+ RAM)

2

Playwright for Python

Playwright is Microsoft's modern alternative. It bundles its own browser binaries, auto-waits for content to render, and has native full_page=True support. It's the best self-hosted option — but you still need to manage browser processes and deal with the ~400MB browser download.

playwright
from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page(viewport={"width": 1280, "height": 800})
    page.goto("https://example.com")
    page.screenshot(path="screenshot.png", full_page=True)
    browser.close()

Better than Selenium, but still:

  • 400MB browser download on first install
  • Browser process management in production
  • Cloudflare and bot-protection sites will block it
  • Not great for serverless — cold starts are brutal

3

SnapRender API (4 lines)

No browser to install, no driver to manage, no process to babysit. Send a POST request with the URL, get back the screenshot as binary. Works from any Python environment — serverless, CI/CD, notebooks, cron jobs.

SnapRender API4 lines
import requests

response = requests.post(
    "https://api.snaprender.dev/v1/screenshot",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"url": "https://example.com"}
)

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

That's the entire working script. pip install requests is likely already in your environment.


Full-page screenshots, custom viewports, JPEG quality

Most screenshot use cases need more than a basic viewport capture. Here's how to get a full-page screenshot at a specific resolution with JPEG compression:

full-page + jpeg
# Full-page screenshot with custom viewport + JPEG quality
response = requests.post(
    "https://api.snaprender.dev/v1/screenshot",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "url": "https://example.com",
        "full_page": True,
        "viewport": {"width": 1440, "height": 900},
        "format": "jpeg",
        "quality": 85
    }
)
ParameterTypeDescription
full_pagebooleanCapture entire scrollable page, not just the viewport
viewportobjectSet width and height in pixels (default 1280x800)
formatstring"png" or "jpeg" (default png)
qualityintegerJPEG quality 1-100 (default 80, ignored for PNG)

Saving to file, uploading to S3, processing with PIL

Once you have the screenshot bytes, you can pipe them anywhere. Here are the two most common follow-up steps:

Upload to S3

Capture and archive screenshots directly to an S3 bucket — useful for monitoring, compliance, or building a visual diff pipeline.

s3 upload
import requests
import boto3

# 1. Take the screenshot
response = requests.post(
    "https://api.snaprender.dev/v1/screenshot",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"url": "https://example.com"}
)

# 2. Upload to S3
s3 = boto3.client("s3")
s3.put_object(
    Bucket="my-screenshots",
    Key="captures/example.png",
    Body=response.content,
    ContentType="image/png"
)

Process with PIL / Pillow

Resize, crop, or watermark screenshots on the fly. The response bytes work directly with Pillow's Image.open().

pillow processing
from PIL import Image
from io import BytesIO
import requests

response = requests.post(
    "https://api.snaprender.dev/v1/screenshot",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"url": "https://example.com", "format": "png"}
)

img = Image.open(BytesIO(response.content))
img = img.resize((640, 400))  # resize
img = img.crop((0, 0, 640, 300))  # crop
img.save("thumbnail.png")

Skip the browser setup

100 free screenshots per month. No browser to install. No credit card.

Get your API key

Frequently asked questions

The easiest way is using a screenshot API like SnapRender. It takes 4 lines of Python code with the requests library — no browser installation or driver management required.

Yes. Selenium requires scrolling hacks, Playwright has a full_page=True parameter, and SnapRender supports full_page in the API request body. All three methods work, but API-based approaches are the most reliable for very long pages.

You need a headless browser. Selenium and Playwright both run real browsers. SnapRender runs a managed browser in the cloud that waits for JavaScript to finish before capturing.

Playwright is generally better — it has a simpler API, auto-waits for content, and supports full-page screenshots natively. Selenium requires more boilerplate and manual waits.

Standard headless browsers get blocked by Cloudflare. SnapRender has built-in Cloudflare bypass via FlareSolverr — just add use_flaresolverr: true to your request.