DEV Community

Custodia-Admin
Custodia-Admin

Posted on • Originally published at pagebolt.dev

How to Take a Screenshot of a Website with Python

How to Take a Screenshot of a Website with Python

Selenium. Playwright. Puppeteer bindings. All require managing browser processes, driver versions, and dependency headaches.

There's a simpler way: send the URL to a screenshot API, get the PNG back.

In this tutorial, I'll show you how to screenshot any website using Python and the PageBolt API — no browser installation, no version pinning, no infrastructure overhead.

The Problem: Browser Driver Complexity

Typical Selenium/Playwright setup:

from selenium import webdriver
from selenium.webdriver.common.by import By

# Download chromedriver, manage versions, handle OS differences
driver = webdriver.Chrome('/path/to/chromedriver')
driver.get('https://example.com')
driver.save_screenshot('screenshot.png')
driver.quit()
Enter fullscreen mode Exit fullscreen mode

Issues:

  • chromedriver version must match your Chrome version
  • Different binary for macOS, Linux, Windows
  • Fails in CI/CD without --no-sandbox hacks
  • 300MB+ of dependencies
  • Slow (browser startup overhead)

The Solution: PageBolt Screenshot API

One API call. Binary PNG back. Done.

import requests

api_key = 'your-pagebolt-api-key'
response = requests.post(
    'https://api.pagebolt.dev/v1/screenshot',
    headers={'Authorization': f'Bearer {api_key}'},
    json={'url': 'https://example.com'}
)

with open('screenshot.png', 'wb') as f:
    f.write(response.content)
Enter fullscreen mode Exit fullscreen mode

That's it. Five lines. No browser management.

Synchronous Version (requests)

Install the requests library:

pip install requests
Enter fullscreen mode Exit fullscreen mode

Basic usage:

import requests

def take_screenshot(url, filename='screenshot.png', api_key=None):
    """Take a screenshot of a website using PageBolt API."""

    if not api_key:
        import os
        api_key = os.getenv('PAGEBOLT_API_KEY')

    if not api_key:
        raise ValueError('PAGEBOLT_API_KEY not set')

    response = requests.post(
        'https://api.pagebolt.dev/v1/screenshot',
        headers={'Authorization': f'Bearer {api_key}'},
        json={
            'url': url,
            'format': 'png',
            'width': 1280,
            'height': 720
        }
    )

    if response.status_code != 200:
        raise Exception(f'API error: {response.status_code} {response.text}')

    with open(filename, 'wb') as f:
        f.write(response.content)

    print(f'✅ Screenshot saved: {filename}')
    print(f'📊 Size: {len(response.content)} bytes')

# Usage
take_screenshot('https://example.com', 'homepage.png')
Enter fullscreen mode Exit fullscreen mode

Asynchronous Version (httpx)

For async/await workflows:

pip install httpx
Enter fullscreen mode Exit fullscreen mode

Async code:

import asyncio
import httpx

async def take_screenshot_async(url, filename='screenshot.png', api_key=None):
    """Async version using httpx."""

    if not api_key:
        import os
        api_key = os.getenv('PAGEBOLT_API_KEY')

    if not api_key:
        raise ValueError('PAGEBOLT_API_KEY not set')

    async with httpx.AsyncClient() as client:
        response = await client.post(
            'https://api.pagebolt.dev/v1/screenshot',
            headers={'Authorization': f'Bearer {api_key}'},
            json={
                'url': url,
                'format': 'png',
                'width': 1280,
                'height': 720
            }
        )

        if response.status_code != 200:
            raise Exception(f'API error: {response.status_code}')

        with open(filename, 'wb') as f:
            f.write(response.content)

        print(f'✅ Screenshot saved: {filename}')

# Usage
asyncio.run(take_screenshot_async('https://example.com', 'homepage.png'))
Enter fullscreen mode Exit fullscreen mode

Batch Screenshots

Screenshot multiple URLs:

import requests
import os

api_key = os.getenv('PAGEBOLT_API_KEY')
urls = [
    'https://example.com',
    'https://example.com/about',
    'https://example.com/pricing'
]

for url in urls:
    filename = url.split('/')[-1] or 'homepage'

    response = requests.post(
        'https://api.pagebolt.dev/v1/screenshot',
        headers={'Authorization': f'Bearer {api_key}'},
        json={'url': url, 'format': 'png'}
    )

    with open(f'{filename}.png', 'wb') as f:
        f.write(response.content)

    print(f'{url}{filename}.png')
Enter fullscreen mode Exit fullscreen mode

Device Emulation

Screenshot on mobile:

response = requests.post(
    'https://api.pagebolt.dev/v1/screenshot',
    headers={'Authorization': f'Bearer {api_key}'},
    json={
        'url': 'https://example.com',
        'format': 'png',
        'viewportDevice': 'iphone_14_pro'  # 25+ devices available
    }
)

with open('mobile-screenshot.png', 'wb') as f:
    f.write(response.content)
Enter fullscreen mode Exit fullscreen mode

Real-World Use Cases

1. Web Scraping: Visual Verification

Screenshot every page you scrape to verify rendering:

from bs4 import BeautifulSoup
import requests

urls = scrape_sitemap('https://example.com/sitemap.xml')

for url in urls:
    # Scrape
    page = requests.get(url).text

    # Screenshot to verify rendering
    screenshot_response = requests.post(
        'https://api.pagebolt.dev/v1/screenshot',
        headers={'Authorization': f'Bearer {api_key}'},
        json={'url': url}
    )

    with open(f'screenshots/{url.split("/")[-1]}.png', 'wb') as f:
        f.write(screenshot_response.content)
Enter fullscreen mode Exit fullscreen mode

2. Monitoring: Daily Screenshots

Screenshot production homepage every hour to catch visual regressions:

import schedule
import time

def daily_screenshot():
    response = requests.post(
        'https://api.pagebolt.dev/v1/screenshot',
        headers={'Authorization': f'Bearer {api_key}'},
        json={'url': 'https://mysite.com'}
    )

    filename = f'screenshots/{datetime.now().isoformat()}.png'
    with open(filename, 'wb') as f:
        f.write(response.content)

schedule.every().hour.do(daily_screenshot)

while True:
    schedule.run_pending()
    time.sleep(60)
Enter fullscreen mode Exit fullscreen mode

3. Testing: Before/After Verification

Screenshot before and after a deployment:

import subprocess

# Pre-deployment screenshot
pre_response = requests.post(
    'https://api.pagebolt.dev/v1/screenshot',
    headers={'Authorization': f'Bearer {api_key}'},
    json={'url': 'https://staging.example.com'}
)
with open('before.png', 'wb') as f:
    f.write(pre_response.content)

# Deploy
subprocess.run(['./deploy.sh'])

# Post-deployment screenshot
post_response = requests.post(
    'https://api.pagebolt.dev/v1/screenshot',
    headers={'Authorization': f'Bearer {api_key}'},
    json={'url': 'https://staging.example.com'}
)
with open('after.png', 'wb') as f:
    f.write(post_response.content)

print('Compare before.png and after.png for visual changes')
Enter fullscreen mode Exit fullscreen mode

Pricing

Free tier: 100 screenshots/month (great for development)
Starter: $29/month for 5,000 screenshots
Growth: $79/month for 25,000 screenshots
Scale: $199/month for 100,000 screenshots

For a script that takes 1 screenshot daily, the free tier covers the entire year.

Environment Setup

# Set your API key as an environment variable
export PAGEBOLT_API_KEY=your-actual-api-key

# Then run your script
python3 screenshot.py
Enter fullscreen mode Exit fullscreen mode

Or in .env:

PAGEBOLT_API_KEY=your-actual-api-key
Enter fullscreen mode Exit fullscreen mode

Load with python-dotenv:

from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('PAGEBOLT_API_KEY')
Enter fullscreen mode Exit fullscreen mode

Next Steps

  1. Get a free PageBolt API key — 100 screenshots/month, no credit card
  2. Copy one of the examples above
  3. Run it: python3 screenshot.py
  4. Build: Add to your web scraper, monitoring, or testing pipeline

Done. No Selenium. No browser management. Just screenshots.

Top comments (0)