How to Take Website Screenshots with Selenium and Chromium
Capture viewport, element, and full-document screenshots with Selenium and Chromium. Learn setup, readiness waits, output handling, troubleshooting, and a browser-free API option.
Selenium can capture a website screenshot in Chromium with driver.save_screenshot("screenshot.png"). That saves the current browser window as a PNG. Use element.screenshot(...) to capture one element. For a full-document capture, Selenium’s Python BiDi API has a separate screenshot method that accepts origin="document"; check that your Selenium and browser versions support the setup you use.
This guide uses Python, Selenium 4, and Chromium. It covers setup, viewport and element captures, document screenshots, output formats, readiness, and common failures.
1. Install Selenium and prepare Chromium
Install Selenium in your project’s environment:
python -m pip install selenium
Selenium’s Chrome documentation says Selenium 4 is compatible with Chrome 75 and greater and advises matching Chrome and ChromeDriver major versions. Selenium Manager may handle driver setup for common configurations, but your environment still needs a compatible browser and driver. Check the installed Selenium release’s documentation if setup differs.
Headless mode is optional. It runs Chromium without displaying a browser window. The --headless=new argument is one of the Chrome arguments documented in Selenium’s Chrome guidance.
2. Capture the current browser window
This complete example opens a page, saves a PNG of the current window, checks the documented Boolean result, and closes the browser even if navigation or saving fails:
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new") # Optional: omit to show the browser window.
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
saved = driver.save_screenshot("screenshot.png")
if not saved:
raise OSError("Screenshot could not be saved")
finally:
driver.quit()
save_screenshot(path) saves the current window as a PNG and returns False on an I/O error. Give it a writable path, and make sure the parent directory already exists.
Save screenshot data as bytes or Base64
If another part of your program needs the screenshot data rather than a file path, Selenium exposes PNG bytes and Base64 forms:
png_bytes = driver.get_screenshot_as_png()
with open("screenshot.png", "wb") as image_file:
image_file.write(png_bytes)
png_base64 = driver.get_screenshot_as_base64()
Use binary mode for PNG bytes. Base64 is text representing the image data, not a PNG file by itself.
3. Capture one element
Locate the element after the page has loaded, then call its screenshot method:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
card = WebDriverWait(driver, 15).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
)
if not card.screenshot("main.png"):
raise OSError("Element screenshot could not be saved")
finally:
driver.quit()
Replace main with a selector that identifies the element you want. Element capture is useful for a chart, card, or other component; it does not produce a full-page screenshot.
4. Capture the full document with Selenium BiDi
The ordinary save_screenshot call captures the current browser window. Selenium’s Python BiDi browsing-context API is a separate route that accepts origin="document" or origin="viewport" and can also accept a clip rectangle. The exact setup and support depend on Selenium and browser versions, so verify the API in your installed version before using it.
For a driver configured with BiDi support and a valid browsing-context identifier, the documented call shape is:
encoded = driver.browsing_context.capture_screenshot(
context=context_id,
origin="document", # Use "viewport" for the viewport origin.
)
# `encoded` is Base64 screenshot data. Decode it to write a PNG file.
import base64
with open("document.png", "wb") as image_file:
image_file.write(base64.b64decode(encoded))
Consult the Selenium BiDi documentation and your installed Python API reference for BiDi enablement and context discovery. Do not assume this method is a drop-in replacement for save_screenshot.
5. Wait for the page state you need
Selenium documents that driver.get(url) waits until the page’s onload event fires. That does not guarantee that asynchronous application updates, lazy-loaded images, fonts, or animations have finished. Wait for a meaningful application state before capturing.
For example, wait until a known element appears:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
driver.get("https://example.com")
WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-page-ready='true']"))
)
driver.save_screenshot("ready.png")
Use a selector that actually reflects readiness on your target site. A fixed sleep can waste time on fast loads and still be too short on slow ones.
6. Choose the capture method and output
| Need | Method | Result |
|---|---|---|
| Current browser window | driver.save_screenshot(path) |
PNG file; Boolean success result |
| Current-window image in memory | get_screenshot_as_png() |
PNG bytes |
| Current-window image as text | get_screenshot_as_base64() |
Base64-encoded image data |
| One located element | element.screenshot(path) |
PNG of that element |
| Document or viewport origin through BiDi | capture_screenshot(context=..., origin=...) |
Base64 screenshot data; version-dependent setup |
The first four are ordinary Selenium WebDriver screenshot methods; the document-origin option is a BiDi API. Pick based on scope and output handling, and verify support in your installed Selenium and browser versions.
7. Troubleshooting
| Symptom | Likely cause | What to do |
|---|---|---|
| Chrome or driver session fails to start | Browser and ChromeDriver major versions do not match, or a browser/driver is unavailable. | Install compatible versions, confirm both are discoverable in the runtime, and check Selenium’s Chrome setup guidance. |
save_screenshot returns False |
The output path could not be written. | Use a writable destination, create the parent directory, and check permissions and available storage. |
| Screenshot is blank or shows a loading state | The page had not reached the application state you wanted when capture occurred. | Wait for a site-specific visible element or readiness condition after navigation. |
| Element screenshot raises an error or captures nothing useful | The selector did not match, or the element was not yet visible. | Check the selector and wait for visibility before calling element.screenshot. |
| Full-document BiDi call is unavailable | The installed Selenium/browser combination or BiDi configuration may not expose the documented method or context. | Check the installed version’s Python API and BiDi setup. Use the ordinary window screenshot if that scope is sufficient. |
| Image data cannot be opened | Base64 text may have been written as if it were raw PNG bytes. | Decode Base64 to bytes before writing, or use get_screenshot_as_png() and write in binary mode. |
8. Performance, reliability, and cost
Screenshot time includes browser startup, navigation, the readiness condition, and image capture. Reusing a browser session for multiple pages can avoid repeated startup, but keep each navigation and capture isolated enough that one page’s state does not leak into another. Always call driver.quit() when finished so the browser process is closed.
For reliable captures, use a deterministic viewport and a page-specific readiness condition. Dynamic content, animation, remote resources, and lazy loading can change what appears in a screenshot. Selenium’s documented onload wait is not a guarantee that all such content has settled.
Selenium and Chromium are software components; the research sources specify no screenshot charge or performance benchmark. Operational cost depends on the machine and infrastructure used to run the browser, including the time and resources consumed by browser sessions.
Or skip the browser setup
ScreenshotNeo is a website screenshot API: one GET request with a URL returns a PNG, JPEG, WebP, or PDF. It can handle captures without you setting up Selenium and Chromium. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
- Cookie banners are accepted and removed before capture; 60+ known consent platforms, newsletter popups, and chat widgets can be removed, with each step configurable.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers report the page verdict and billing status.
- An MCP server lets AI agents, including Claude and Cursor, use screenshot, page-info, and PDF tools.
- 1,000 screenshots per month are free with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month, with no card.
FAQ
Does save_screenshot create a JPEG?
No. The documented method saves a PNG. Use an image library to convert formats if your workflow requires JPEG or another format.
Does headless Chromium change the screenshot method?
No. Headless mode is a browser launch option; after starting the driver, the same Selenium screenshot methods apply.
Can I use Selenium screenshots for pages behind authentication?
Selenium captures the page available to its browser session. Your test must establish the required authenticated state before capturing; the screenshot methods do not sign in by themselves.
Where can I check the exact Python method signature?
Use the API reference for the Selenium version installed in your environment. Selenium’s official documentation and API docs describe its browser automation interfaces.


