Selenium Alternative for Screenshots and PDF Generation: Skip the WebDriver
Selenium is the standard for browser automation testing. But if what you actually need is a screenshot or a PDF — not assertions, not element interactions — Selenium is a lot of machinery for a simple output.
The setup alone: install selenium, download a WebDriver binary, match the browser version, configure the driver, handle platform differences between local and CI. Then manage the browser lifecycle in code.
Here's what the same job looks like without any of that.
Screenshot: Selenium vs API
Selenium (Python):
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome(options=options)
driver.set_window_size(1280, 800)
driver.get('https://example.com')
driver.save_screenshot('screenshot.png')
driver.quit()
Requires: selenium, chromedriver, matching Chrome version, webdriver-manager in CI.
API (Python):
import requests
res = requests.post(
'https://api.pagebolt.dev/v1/screenshot',
headers={'x-api-key': 'YOUR_API_KEY'},
json={'url': 'https://example.com', 'fullPage': True, 'blockBanners': True}
)
with open('screenshot.png', 'wb') as f:
f.write(res.content)
Requires: requests. That's it.
PDF generation
Selenium has no native PDF export for arbitrary pages. The common workaround is Chrome DevTools Protocol (execute_cdp_cmd) — which works, but adds complexity and is Chrome-specific.
import base64
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument('--headless=new')
driver = webdriver.Chrome(options=options)
driver.get('https://example.com')
pdf = driver.execute_cdp_cmd('Page.printToPDF', {'printBackground': True})
with open('page.pdf', 'wb') as f:
f.write(base64.b64decode(pdf['data']))
driver.quit()
With an API:
res = requests.post(
'https://api.pagebolt.dev/v1/pdf',
headers={'x-api-key': 'YOUR_API_KEY'},
json={'url': 'https://example.com', 'format': 'A4', 'printBackground': True}
)
with open('page.pdf', 'wb') as f:
f.write(res.content)
Same result. No ChromeDriver, no CDP, no base64 decode.
When to keep Selenium
Selenium is the right choice when you need:
- Cross-browser testing (Chrome + Firefox + Safari)
- Complex element interactions with assertions (
assert element.text == 'Expected') - Page object models and test frameworks (pytest-selenium, etc.)
- Fine-grained control over browser state between test steps
If your code ends with driver.save_screenshot() or a CDP PDF call and no assertions, that's the sign you're using Selenium as a file generator, not a test runner.
Batch screenshots in parallel
import asyncio, aiohttp
async def screenshot(session, url, filename):
async with session.post(
'https://api.pagebolt.dev/v1/screenshot',
headers={'x-api-key': 'YOUR_API_KEY'},
json={'url': url, 'fullPage': True, 'blockBanners': True}
) as resp:
with open(filename, 'wb') as f:
f.write(await resp.read())
async def main():
urls = [('https://site-a.com', 'a.png'), ('https://site-b.com', 'b.png')]
async with aiohttp.ClientSession() as session:
await asyncio.gather(*[screenshot(session, u, f) for u, f in urls])
asyncio.run(main())
Selenium with parallel sessions requires multiple driver instances, which multiplies memory usage. With an API, you fire concurrent requests and the browser infrastructure scales on the other end.
Get Started Free
100 requests/month, no credit card
Screenshots, PDFs, and batch parallel captures via API — no WebDriver, no browser binary, no lifecycle management.
Get Your Free API Key →