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?
- 15+ lines of setup code
- Managing ChromeDriver binary
- Polling for page load
- Brittle selectors
- Browser process overhead
- On CI/CD, you need to install headless Chrome
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
| Task | Selenium | PageBolt |
|---|---|---|
| Take 1 screenshot | 15+ lines | 5 lines |
| Take 100 screenshots | Spawn 100 browsers OR complex queue logic | 100 HTTP requests in a loop |
| Set up in Docker | RUN apt-get install chromium | Already included |
| Cost at scale | $500–1,000/mo (infrastructure) | $29–79/mo (API) |
| Development time | 2–3 hours | 15 minutes |
| Debugging | WebDriver logs, browser crashes | HTTP 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
- Complex, long-running workflows (10+ minute interactions). REST APIs have timeouts.
- Full browser debugging with DevTools. PageBolt doesn't expose the browser sandbox.
- Custom JavaScript evaluation with full DOM access. The REST API limits script execution.
For everything else — screenshots, PDFs, responsive testing, batch automation — the REST API is simpler, cheaper, and faster.
Getting Started
- Create a free account at pagebolt.dev (100 requests/month, no credit card)
- Get your API key from the dashboard
- Install requests:
pip install requests - 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.