How to Crop a Selenium Webpage Screenshot to the Browser Viewport
Selenium screenshots may already show only the browser viewport. Learn how to check the PNG and crop verified bounds when a capture includes extra content.
A Selenium screenshot of the current browser window may already be limited to the visible page viewport. Inspect the PNG dimensions and contents first. If your chosen screenshot method produced a full-document image or other extra area, crop it with bounds measured for that browser, driver, and capture method. Selenium window dimensions help configure the browser, but they are not a universal formula for screenshot pixel bounds.
1. Check what Selenium captured
In Selenium’s Python WebDriver API, get_screenshot_as_png() returns PNG bytes for the current window, and get_screenshot_as_file(filename) saves a PNG. A standard current-window capture may already be exactly the viewport you need; do not crop it just because the page itself is taller than the screen.
Open the PNG and inspect its width, height, and visible content. Compare the image with the viewport you intended to capture. The screenshot’s pixel dimensions can differ from CSS viewport dimensions, so use the produced image as the source of truth.
2. Capture and crop in Python
Install Selenium and Pillow in your Python environment:
python -m pip install selenium pillow
This runnable example opens a page, captures the current window, reports the PNG dimensions, and crops a rectangle you provide. Set the four crop coordinates only after measuring the actual output. Pillow uses (left, upper, right, lower) coordinates, with the right and lower edges excluded.
from io import BytesIO
from pathlib import Path
from PIL import Image
from selenium import webdriver
url = "https://example.com"
output_path = Path("viewport.png")
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
# Set a browser window size as a rendering input. Verify the screenshot pixels separately.
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get(url)
# Selenium returns PNG bytes for the current window.
png = driver.get_screenshot_as_png()
image = Image.open(BytesIO(png)).convert("RGB")
print(f"Screenshot dimensions: {image.width} x {image.height}")
# Replace these example values with bounds measured for this exact output.
# Coordinates are pixels: left, upper, right, lower.
crop_bounds = (0, 0, image.width, image.height)
left, upper, right, lower = crop_bounds
if not (0 <= left < right <= image.width and 0 <= upper < lower <= image.height):
raise ValueError(f"Crop bounds {crop_bounds} exceed image size {image.size}")
image.crop(crop_bounds).save(output_path, format="PNG")
print(f"Saved {output_path}")
finally:
driver.quit()
The default crop in the example retains the whole screenshot. Change it only if inspection shows unwanted pixels or content. For example, if you verify that the desired viewport occupies pixels from (0, 0) through (1365, 768), use (0, 0, 1365, 768). Do not copy those sample dimensions without checking your own image.
Save the screenshot first, then inspect it
For a quick visual check, save Selenium’s output directly:
from selenium import webdriver
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
driver.get_screenshot_as_file("selenium-output.png")
finally:
driver.quit()
Open selenium-output.png and check whether it already contains only the visible page area. If so, use it without a crop. If you do crop, keep the original file until you have checked that the result preserves the intended viewport edges.
3. Measure bounds for your browser setup
Use the same browser, driver, headless or headed mode, device scale, and screenshot method that will produce your real captures. A reliable measurement process is:
- Capture a representative page and record the PNG’s pixel width and height.
- Identify the intended viewport rectangle in that PNG, including its origin and edges.
- Check the rectangle visually or against known page content near all four edges.
- Repeat with the browser configuration used in production, especially if it differs from your local setup.
- Store the verified bounds with that configuration. Recheck them when the browser, driver, or capture method changes.
Selenium provides get_window_size(), get_window_rect(), and methods to set window dimensions. These are useful for configuring and recording the browser window, but the documentation does not define one cross-browser calculation that converts those values into crop bounds in screenshot pixels. Browser chrome, output scaling, and the screenshot method can affect the relationship.
4. Full-page and full-document screenshots
Some Selenium APIs can capture beyond the visible viewport. For example, Firefox’s Python API exposes full-document screenshot methods. Selenium’s Ruby screenshot API documents a full_page option when supported; that API page labels the module private, so availability may change. These binding-specific features should not be assumed to exist in every language and browser combination.
If you intentionally used a full-document method, crop the resulting image to the viewport rectangle measured in that image. Confirm both the pixel scale and where the viewport begins. A full-page image may be taller than the viewport, but its top-left origin and scaling still need to be checked before applying coordinates.
5. Wait for the page state you need
A successful screenshot call does not guarantee that asynchronous content has finished rendering. If the capture must include a particular element, wait for it explicitly before taking the screenshot. For example:
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
WebDriverWait(driver, 15).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "main"))
)
png = driver.get_screenshot_as_png()
Choose a condition that represents the page state you need. A visible main element may not mean that images, fonts, or client-rendered content are ready. Add an application-specific condition when those resources matter; avoid relying on an arbitrary sleep unless the page offers no better signal.
6. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The screenshot already looks like the viewport | The current-window screenshot is already the desired capture. | Skip cropping and use the original PNG. |
| The crop cuts off content or includes too much | Bounds were guessed, measured in CSS pixels, or copied from another browser setup. | Inspect the actual PNG and remeasure pixel coordinates for the exact browser, driver, mode, and screenshot method. |
| Pillow raises an error about the crop box | A coordinate is negative, the right or lower edge exceeds the image, or the rectangle has zero width or height. | Check that 0 <= left < right <= width and 0 <= upper < lower <= height. |
| Output dimensions do not match the requested window size | Window dimensions are not a guaranteed direct mapping to screenshot pixel dimensions. | Read the PNG dimensions and validate the desired rectangle in the image itself. |
| Content is missing from the screenshot | The page or a specific element was not ready when capture ran. | Wait for a meaningful element or application state, then capture again. |
| A full-page method is unavailable | The method may be binding-, browser-, or version-specific. | Check the documentation for your exact Selenium binding and browser. A normal current-window screenshot may suffice if only the visible viewport is needed. |
| The browser session fails before capture | The browser or driver could not start, or the driver does not match the environment. | Resolve the WebDriver startup or compatibility issue first; image cropping cannot repair a failed browser capture. |
7. Performance, reliability, and cost
For repeated captures, reuse a WebDriver session when suitable, and crop in memory from the PNG bytes rather than writing and rereading a temporary file. Keep the capture and crop steps deterministic by pinning the browser environment and validating the output dimensions. Cropping itself is a local image-processing step; no Selenium documentation cited here provides a benchmark, so measure the end-to-end workflow under your own workload.
For reliability, retain the original screenshot during development, log its pixel dimensions and the bounds applied, and fail clearly when bounds fall outside the image. Revalidate after changing browser versions, headless mode, window setup, or screenshot API. Selenium itself is browser automation software; infrastructure and browser execution costs depend on where and how you run it.
Or skip the browser setup
If your goal is a clean page image rather than controlling Selenium directly, ScreenshotNeo is a website screenshot API and MCP server. Its GET endpoint accepts a URL and returns an image or PDF. Here is the one-call cURL version:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options and setup. Cookie banners, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
FAQ
Does a Selenium screenshot include browser tabs and toolbars?
The documented Python current-window screenshot captures the browser window’s page context, rather than a desktop screenshot. Check unusual driver output, but browser chrome is not normally part of the page image.
Can I use the same crop coordinates in every browser?
No universal formula is documented. Verify coordinates against the PNG from the exact browser and driver configuration.
Should I crop a normal Selenium screenshot?
Only if inspecting the output shows extra area you need to remove. A current-window capture may already be the viewport image.
Sources
- Selenium Python WebDriver API: current-window screenshot methods and window size and rectangle methods.
- Selenium: Working with windows and tabs: window dimension guidance.
- Selenium Firefox Python API and Selenium Ruby TakesScreenshot API: binding-specific full-document and full-page options.


