Yes. Selenium WebDriver can capture screenshots while Chrome, Firefox, and other supported browsers run in headless mode. Enable the browser’s headless option, set a deliberate viewport if dimensions matter, navigate to the page, and use the same screenshot method you would use with a visible browser.
How a headless Selenium screenshot works
Headless mode means the browser runs without displaying its normal graphical window. It does not remove WebDriver’s screenshot API: Selenium captures the current browsing context through the driver, or a specific element through the element screenshot capability. A standard driver screenshot is not automatically a full-document capture.
The official Selenium documentation describes screenshots as captures of the current browsing context. The Java TakesScreenshot API describes a driver or HTML element that can capture a screenshot and store it in different ways.
Python: capture a headless Chrome screenshot
Install Selenium with python -m pip install selenium. This example uses Selenium’s Chrome options, sets a viewport, opens a page, and saves a PNG. Selenium Manager can handle driver setup for supported installations; if your environment requires a separately managed driver, ensure it matches the browser version.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minute#1 Best Overall
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless")
options.add_argument("--window-size=1280,900")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
driver.save_screenshot("screenshot.png")
finally:
driver.quit()
save_screenshot writes a PNG file and returns a success value. Python also provides get_screenshot_as_file(filename), get_screenshot_as_png() for PNG bytes, and get_screenshot_as_base64() for a Base64 string. These methods are documented in Selenium’s Python WebDriver API.
Return bytes instead of writing a file
png_bytes = driver.get_screenshot_as_png()
with open("screenshot.png", "wb") as image_file:
image_file.write(png_bytes)
Use the bytes form when another part of your program uploads or processes the image directly. Base64 is useful when the receiving format expects encoded image data, such as an HTML data URL, but it is larger than the underlying binary representation.
JavaScript, Java, C#, and Ruby
Selenium documents screenshot methods across these bindings. The browser’s headless option is configured in its browser-specific options; the screenshot call remains a WebDriver operation.
JavaScript with Chrome
Install the Selenium JavaScript package and a compatible Chrome installation. The official Selenium example uses --headless and takeScreenshot(); the returned value is an encoded screenshot string.
const { Builder } = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const fs = require('node:fs/promises');
(async () => {
const options = new chrome.Options().addArguments('--headless');
const driver = await new Builder()
.forBrowser('chrome')
.setChromeOptions(options)
.build();
try {
await driver.manage().window().setRect({ width: 1280, height: 900 });
await driver.get('https://example.com');
const base64 = await driver.takeScreenshot();
await fs.writeFile('screenshot.png', Buffer.from(base64, 'base64'));
} finally {
await driver.quit();
}
})();
Java
In Java, cast the driver to TakesScreenshot and request a file output. The Selenium API also documents Base64 output.
Rank #2
ChromeOptions options = new ChromeOptions();
options.addArguments("--headless");
WebDriver driver = new ChromeDriver(options);
try {
driver.manage().window().setSize(new Dimension(1280, 900));
driver.get("https://example.com");
File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
Files.copy(screenshot.toPath(), Path.of("screenshot.png"),
StandardCopyOption.REPLACE_EXISTING);
} finally {
driver.quit();
}
Use imports for org.openqa.selenium.*, org.openqa.selenium.chrome.ChromeOptions, java.io.File, and java.nio.file.*. Your project must include Selenium’s Java client dependency.
C# and Ruby
Selenium’s official examples use GetScreenshot().SaveAsFile(...) in C# and driver.save_screenshot(...) in Ruby. Configure the relevant browser driver for headless mode first, then call the binding’s screenshot method.
Viewport, element, and full-page captures
Viewport screenshot
A normal driver screenshot captures the current browsing context. For stable visual comparisons, choose a consistent viewport size before navigation or capture; otherwise, browser defaults and environment differences can change wrapping, responsive breakpoints, and resulting dimensions. Selenium documents window management APIs, and Chrome’s headless command-line reference gives --screenshot --window-size=412,892 as a supported command-line pattern.
Free tools Windows power users keep installed
One-click scans. No signup required.
Element screenshot
To capture one element rather than the browsing context, locate the element and use the element’s screenshot method in the binding. This is a distinct operation from taking a driver screenshot. It is useful for a component or card, but depends on the element being present and available in the page when captured.
Full-document screenshot
Do not assume an ordinary screenshot automatically includes content below the viewport. Firefox’s Python driver exposes the separate methods get_full_page_screenshot_as_file, save_full_page_screenshot, get_full_page_screenshot_as_png, and get_full_page_screenshot_as_base64. These are Firefox-specific full-document methods, distinct from a standard viewport capture. Check the API for the exact browser and binding you use before relying on equivalent functionality elsewhere.
Rank #3
Choose file, bytes, or Base64 output
| Output form | Best fit | Practical consideration |
|---|---|---|
| File | Saving a capture as an artifact or inspecting it manually. | Ensure the process has permission to write to the target path. |
| PNG bytes | Passing image data directly to another function or upload client. | Keep the data binary; do not decode it as text. |
| Base64 | Embedding into a data URL or passing through a text-only interface. | Decode it before writing a PNG file. |
The exact method names vary by language binding. Python documents all three forms; Java documents file and Base64 output in its screenshot interface, and JavaScript’s documented takeScreenshot() returns an encoded string.
Timing and reproducibility
A screenshot captures what the browser has rendered at capture time. A successful navigation call does not necessarily mean a page’s asynchronous images, fonts, or client-side content have finished updating. If the target depends on dynamic content, wait for a meaningful page condition—such as the presence of a selector—before taking the screenshot rather than relying on an arbitrary pause. Keep the wait tied to the page’s actual readiness requirement.
- Set a fixed viewport for repeatable dimensions and responsive layout.
- Wait for the specific content that must appear in the image.
- Use the element screenshot method for a component, not as a substitute for full-document capture.
- Use Firefox’s documented full-page methods when full-document capture is required and Firefox is an acceptable choice.
Troubleshooting headless screenshots
The browser starts, but the screenshot is blank or incomplete
The capture may have occurred before the relevant content rendered, or the page may require a particular interaction or state. Wait for a specific element or state and verify that the page is at the intended URL before capturing. For long pages, confirm that you are using a full-page capability rather than expecting the normal viewport screenshot to include off-screen content.
Screenshot dimensions change between runs
Set the window size explicitly and keep it consistent across runs. Responsive sites can rearrange content at different viewport widths, so comparing images captured at different sizes is not a reliable pixel comparison.
The output file is missing
Check the process’s current working directory and write permissions. Prefer an explicit path if a job runner or container starts from a different directory than your local shell. For APIs that return bytes or Base64, ensure your code writes or decodes that return value instead of expecting a file to appear automatically.
The element capture fails
Confirm that the element is located successfully before the screenshot call and that the page has reached the state in which the element exists. If the goal is the whole page or current view, call the driver screenshot method rather than an element method.
The browser or driver will not launch
Headless mode does not eliminate the need for a functioning browser installation and a compatible WebDriver setup. Check the browser and driver versions, startup logs, and runtime environment. In managed or container environments, verify that the process has the required permissions and dependencies for launching the browser.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
For a one-request screenshot without configuring Selenium and a browser driver, ScreenshotNeo accepts a URL and returns a screenshot or PDF. Its clean-shot flow accepts cookie or consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. ScreenshotNeo also provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for AI agents.
cURL example, with the target URL adapted from the documented example:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
See the ScreenshotNeo API documentation for request options. Its Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month with no card.
Recommended Free Tools
Cost and operational notes
With Selenium, the screenshot call itself is part of your browser automation workflow: you supply and operate the browser environment, then save or transmit the resulting image. Account for browser startup, page loading, waits, and output storage in the runtime of the whole job; the official screenshot references cited here do not publish an independent performance benchmark. For hosted capture, check the service’s documented billing behavior and capture controls against your needs rather than assuming all unsuccessful navigations are charged equally.
Best Value
ScreenshotNeo’s listed plans are Free, 1,000 shots per month with no card; Starter, $5 for 3,000; Growth, $15 for 15,000; Pro, $39 for 60,000; Scale, $99 for 250,000; and Business, $249 for 1,000,000. Yearly billing gives two months free, and every feature is on every plan. These prices and allowances describe ScreenshotNeo plans, not Selenium costs.
Frequently Asked Questions
Can Selenium take screenshots without a display?
Yes. Run a supported browser in headless mode and use its Selenium screenshot method.
Does a standard Selenium screenshot capture the whole page?
Not necessarily. A normal driver screenshot captures the current browsing context; full-document capture is a separate capability, such as Firefox’s documented Python full-page methods.
Can I capture a screenshot as bytes instead of a file?
Yes. Python provides PNG bytes and Base64 methods, and Selenium bindings differ in the output forms they expose.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

