Guide Mar 28, 2026

How to Take Screenshots and Generate PDFs in Python (No Selenium Required)

One HTTP call with the requests library replaces the entire Selenium stack. Screenshots, PDFs, and page inspection without managing a browser, WebDriver, or headless Chrome.

Python developers who need to automate browser tasks have traditionally reached for Selenium or Playwright. Both work, but both come with friction: WebDriver management, dependency hell, browser binary installation, and debugging timeouts.

There's a simpler path: one HTTP call with the requests library replaces the entire Selenium stack.

This article shows you how to take screenshots, generate PDFs, and inspect web pages in Python — without managing a browser at all.

The Old Way: Selenium (Verbose & Heavy)

Here's what taking a screenshot in Selenium looks like:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.service import Service

# Download driver, start browser, navigate
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)

driver.get("https://example.com")
WebDriverWait(driver, 10).until(
    lambda d: d.find_element(By.TAG_NAME, "body")
)

driver.save_screenshot("screenshot.png")
driver.quit()

What's wrong with this?

The New Way: REST API (One HTTP Call)

Here's the same task with PageBolt:

import requests

response = requests.post(
    "https://pagebolt.dev/api/v1/screenshot",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={"url": "https://example.com"}
)

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

That's it. One function. One HTTP request. One line to save the file.

No browser to manage. No CI/CD setup. Works everywhere Python runs.

Real Examples: Screenshots + PDFs

Example 1: Screenshot a Responsive Device

import requests

payload = {
    "url": "https://example.com",
    "viewport_device": "iphone_14_pro",  # 25+ device presets available
    "block_banners": True,                # Hide GDPR popups
    "block_ads": True                     # Hide ads
}

response = requests.post(
    "https://pagebolt.dev/api/v1/screenshot",
    headers={"x-api-key": "YOUR_API_KEY"},
    json=payload
)

if response.status_code == 200:
    with open("screenshot-iphone.png", "wb") as f:
        f.write(response.content)
    print("Screenshot saved")
else:
    print(f"Error: {response.json()}")

Output: A pristine iPhone 14 Pro screenshot of your website, no Chrome installation required.

Example 2: Generate a PDF Invoice

import requests

html_content = """
<html>
  <body style="font-family: Arial; padding: 20px;">
    <h1>Invoice #12345</h1>
    <p>Total: $1,200.00</p>
    <p>Date: 2026-03-28</p>
  </body>
</html>
"""

response = requests.post(
    "https://pagebolt.dev/api/v1/pdf",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={"html": html_content}
)

with open("invoice.pdf", "wb") as f:
    f.write(response.content)

Done. No wkhtmltopdf, no node-html-pdf, no Puppeteer. Just HTTP and file I/O.

Example 3: Batch Screenshot Multiple URLs

import requests

urls = [
    "https://github.com",
    "https://stackoverflow.com",
    "https://python.org"
]

for url in urls:
    response = requests.post(
        "https://pagebolt.dev/api/v1/screenshot",
        headers={"x-api-key": "YOUR_API_KEY"},
        json={"url": url}
    )

    filename = url.replace("https://", "").replace("/", "_") + ".png"
    with open(filename, "wb") as f:
        f.write(response.content)

    print(f"Saved {filename}")

Three URLs, three HTTP requests, three screenshots. No browser management.

Why This Matters for Python Developers

1. Zero Infrastructure

Selenium requires Chrome + WebDriver. PageBolt's server handles all of that. Your Python environment is just pip install requests — that's it.

2. Massively Faster for Concurrent Requests

Want to screenshot 1,000 pages in parallel? With Selenium, you spawn 1,000 browser instances (memory nightmare). With PageBolt, you send 1,000 HTTP requests in concurrent threads:

import requests
from concurrent.futures import ThreadPoolExecutor

urls = ["https://example.com/page1", "https://example.com/page2"]  # add more

def screenshot_url(url):
    response = requests.post(
        "https://pagebolt.dev/api/v1/screenshot",
        headers={"x-api-key": "YOUR_API_KEY"},
        json={"url": url}
    )
    filename = url.split("/")[-1] + ".png"
    with open(filename, "wb") as f:
        f.write(response.content)

with ThreadPoolExecutor(max_workers=10) as executor:
    executor.map(screenshot_url, urls)

1,000 screenshots in seconds. No browser overhead.

3. No CI/CD Headaches

GitHub Actions? Docker? Heroku? They just work. No need to install headless Chrome, manage ChromeDriver versions, or debug WebDriver timeouts.

4. Faster Development

Write the request, send it, save the file. No setup, no state management, no flaky waits.

Real-World Use Case: Automated Report Generation

import requests
from datetime import datetime

# Generate an HTML report
html = f"""
<html>
  <body style="font-family: Arial;">
    <h1>Monthly Report</h1>
    <p>Generated: {datetime.now().strftime('%Y-%m-%d')}</p>
    <p>Total requests: 50,000</p>
    <p>Uptime: 99.9%</p>
  </body>
</html>
"""

# Convert to PDF
response = requests.post(
    "https://pagebolt.dev/api/v1/pdf",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={"html": html}
)

with open("report.pdf", "wb") as f:
    f.write(response.content)

print("Report generated and saved as report.pdf")

No Puppeteer. No wkhtmltopdf. Just Python + HTTP.

Comparing: Selenium vs REST API

TaskSeleniumPageBolt
Take 1 screenshot15+ lines5 lines
Take 100 screenshotsSpawn 100 browsers OR complex queue logic100 HTTP requests in a loop
Set up in DockerRUN apt-get install chromiumAlready included
Cost at scale$500–1,000/mo (infrastructure)$29–79/mo (API)
Development time2–3 hours15 minutes
DebuggingWebDriver logs, browser crashesHTTP status codes, JSON errors

API Reference (Quick Cheat Sheet)

Screenshot:

requests.post(
    "https://pagebolt.dev/api/v1/screenshot",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "url": "https://example.com",
        "viewport_device": "iphone_14_pro",  # optional
        "block_banners": True,                # optional
        "block_ads": True,                    # optional
        "full_page": True                     # optional: capture entire scrollable page
    }
)

PDF:

requests.post(
    "https://pagebolt.dev/api/v1/pdf",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "url": "https://example.com",  # OR "html": "<html>...</html>"
        "landscape": False,             # optional
        "margin": "1cm"                # optional
    }
)

Page Inspection (for AI agents & web scraping):

response = requests.post(
    "https://pagebolt.dev/api/v1/inspect",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={"url": "https://example.com"}
)

data = response.json()
# Returns all buttons, forms, links, headings with CSS selectors
print(data["buttons"])  # [{"selector": "#submit", "text": "Submit", ...}, ...]

When Selenium Still Wins

For everything else — screenshots, PDFs, responsive testing, batch automation — the REST API is simpler, cheaper, and faster.

Getting Started

  1. Create a free account at pagebolt.dev (100 requests/month, no credit card)
  2. Get your API key from the dashboard
  3. Install requests: pip install requests
  4. Run your first screenshot
import requests

response = requests.post(
    "https://pagebolt.dev/api/v1/screenshot",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={"url": "https://example.com"}
)

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

print("Screenshot saved as test.png")

Final Thought

Selenium and Playwright are powerful tools for complex browser automation. But for the 80% of use cases — taking screenshots, generating PDFs, testing responsive design — they're overkill. A REST API is simpler, faster, and cheaper.

Python's strength is simplicity. Why fight with Selenium when one HTTP call does the job?

Try the Python screenshot API — free

100 requests/month, no credit card. Screenshots, PDFs, page inspection — one pip install requests away.

Get API key free →