How to Take a Screenshot in Python (No Browser Required)
You need to screenshot a webpage. Your first instinct: "Use Selenium or Playwright."
Your second thought: "Wait, that requires installing Chrome, managing WebDriver, and writing 15 lines of boilerplate."
There's a faster way: one HTTP call with Python's built-in requests library.
This tutorial shows you how to take pixel-perfect screenshots in Python—with zero browser management.
The Problem: Selenium Is Overkill for Screenshots
Here's what taking a screenshot in Selenium looks like:
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.service import Service
# Download and manage ChromeDriver
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service)
# Navigate and wait
driver.get("https://example.com")
driver.implicitly_wait(10)
# Take screenshot
driver.save_screenshot("screenshot.png")
driver.quit()
The friction:
- 3 imports + 3 setup lines before you can navigate
- ChromeDriver binary management
- Implicit waits (flaky)
- Browser process overhead
- On CI/CD, you need headless Chrome installed
For the simple task of "capture this URL as PNG," that's a lot of ceremony.
The Solution: 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)
Done. One function. One HTTP request. No browser. No setup.
Step-by-Step Tutorial
1. Get Your API Key
Visit pagebolt.dev and create a free account (100 requests/month, no credit card).
Copy your API key from the dashboard.
2. Install the requests Library
pip install requests
That's your only dependency.
3. Write the Script
Create a file called screenshot.py:
import requests
api_key = "YOUR_API_KEY"
url = "https://example.com"
response = requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": api_key},
json={"url": url}
)
if response.status_code == 200:
with open("screenshot.png", "wb") as f:
f.write(response.content)
print("✅ Screenshot saved as screenshot.png")
else:
print(f"❌ Error: {response.status_code} - {response.text}")
4. Run It
python screenshot.py
Check your current directory. screenshot.png exists.
Real-World Examples
Example 1: Screenshot Multiple URLs
import requests
api_key = "YOUR_API_KEY"
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": api_key},
json={"url": url}
)
if response.status_code == 200:
filename = url.replace("https://", "").replace("/", "_") + ".png"
with open(filename, "wb") as f:
f.write(response.content)
print(f"✅ Saved {filename}")
else:
print(f"❌ Failed: {url}")
Example 2: Screenshot a Mobile Device
import requests
response = 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" # 25+ device presets available
}
)
with open("mobile-screenshot.png", "wb") as f:
f.write(response.content)
Example 3: Screenshot with Ads Blocked
import requests
response = requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"url": "https://example.com",
"block_ads": True, # Hide advertisements
"block_banners": True # Hide GDPR popups
}
)
with open("clean-screenshot.png", "wb") as f:
f.write(response.content)
Example 4: Full-Page Screenshot
import requests
response = requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": "YOUR_API_KEY"},
json={
"url": "https://example.com",
"full_page": True # Capture entire scrollable page
}
)
with open("full-page.png", "wb") as f:
f.write(response.content)
Handling Errors Gracefully
import requests
import json
def take_screenshot(url, api_key, filename="screenshot.png"):
"""Take a screenshot and handle errors."""
try:
response = requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": api_key},
json={"url": url},
timeout=30
)
if response.status_code == 200:
with open(filename, "wb") as f:
f.write(response.content)
return True, f"Screenshot saved: {filename}"
else:
error = response.json()
return False, f"API Error: {error.get('message', 'Unknown error')}"
except requests.exceptions.Timeout:
return False, "Request timeout (30s)"
except requests.exceptions.ConnectionError:
return False, "Connection error"
except Exception as e:
return False, f"Unexpected error: {str(e)}"
# Usage
success, message = take_screenshot("https://example.com", "YOUR_API_KEY")
print(message)
Batch Processing with Concurrency
import requests
from concurrent.futures import ThreadPoolExecutor
def screenshot_url(url, api_key):
"""Screenshot a single URL."""
response = requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": api_key},
json={"url": url}
)
if response.status_code == 200:
filename = url.replace("https://", "").replace("/", "_") + ".png"
with open(filename, "wb") as f:
f.write(response.content)
return f"✅ {filename}"
else:
return f"❌ {url}"
# Screenshot 10 URLs in parallel
urls = [
"https://github.com",
"https://example.com",
# ... 8 more URLs
]
api_key = "YOUR_API_KEY"
with ThreadPoolExecutor(max_workers=5) as executor:
results = executor.map(
lambda url: screenshot_url(url, api_key),
urls
)
for result in results:
print(result)
10 screenshots in seconds. No browser overhead.
Why This Approach Wins
| Metric | Selenium | REST API |
|---|---|---|
| Lines of setup | 8–10 | 0 |
| Dependencies | webdriver-manager, selenium | requests |
| Browser binary | Required | Not required |
| Concurrent screenshots | Hard (spawn many browsers) | Easy (HTTP requests) |
| CI/CD setup | Complex (install Chrome) | 1 line (pip install) |
| Time to first screenshot | 5–10 seconds | 1–2 seconds |
API Reference (Quick)
Basic screenshot:
requests.post(
"https://pagebolt.dev/api/v1/screenshot",
headers={"x-api-key": "YOUR_API_KEY"},
json={"url": "https://example.com"}
)
Common parameters:
{
"url": "https://example.com",
"viewport_device": "iphone_14_pro", # 25+ presets
"full_page": True, # Capture entire page
"block_ads": True, # Hide ads
"block_banners": True, # Hide GDPR popups
"dark_mode": True # Emulate dark theme
}
All parameters: https://pagebolt.dev/docs
When to Use REST API vs Selenium
Use PageBolt REST API if:
- You just need to take screenshots
- You want fast, simple code
- You're running on CI/CD
- You need to screenshot many URLs in parallel
- Cost matters (no infrastructure overhead)
Use Selenium if:
- You need full browser control (click, type, navigate)
- You need to interact with JavaScript-heavy pages
- You need browser DevTools access for debugging
- You have complex, long-running workflows
For pure screenshot capture, the REST API wins on simplicity, speed, and cost.
Getting Started Now
- Create account: https://pagebolt.dev (free, no credit card)
- Copy your API key
- Install requests:
pip install requests - Run the code above
- You're done
Try it free: 100 requests/month. pagebolt.dev
Top comments (0)