How to Take a Website Screenshot with Selenium and ChromeDriver on Windows 11
Set up Selenium on Windows 11, open a page in Chrome, wait for the content you need, and save a PNG screenshot to a known path.
On Windows 11, install Selenium in a Python virtual environment, then use Selenium WebDriver to open Chrome, navigate to a URL, and call driver.save_screenshot(path). Selenium Manager normally resolves ChromeDriver for you, so try webdriver.Chrome() before downloading a driver manually. This saves a PNG of the current browser window; it does not automatically stitch a long page into one full-page image.
1. Install Python and Selenium
Use a Python installation available through the Windows py launcher. In PowerShell, create a project folder and virtual environment, activate it, and install Selenium:
mkdir selenium-screenshot
cd selenium-screenshot
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U selenium
If PowerShell blocks activation under your local policy, you can invoke the environment’s Python directly instead:
.\.venv\Scripts\python.exe -m pip install -U selenium
.\.venv\Scripts\python.exe screenshot.py
Use a virtual environment so the Selenium package for this project is separate from other Python projects. Selenium’s installation guide covers supported installation approaches.
2. Save a screenshot of the current Chrome window
Save this as screenshot.py. It creates the destination directory if needed, navigates to an example URL, saves a PNG, checks Selenium’s return value, and closes the browser even if navigation or capture raises an error.
from pathlib import Path
from selenium import webdriver
output = Path.home() / "Pictures" / "website.png"
output.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
saved = driver.save_screenshot(str(output))
if not saved:
raise OSError(f"Could not save screenshot to {output}")
print(f"Screenshot saved to {output}")
finally:
driver.quit()
Run it from the activated environment:
python screenshot.py
The file is written to the current Windows user’s Pictures directory. Change output to a specific absolute path if your workflow needs a fixed location, for example Path(r"C:\screenshots\website.png"). Create its parent folder as shown above and ensure the process has write access.
The basic flow—create a Chrome driver, navigate with get(), save with save_screenshot(), and close with quit()—matches Selenium’s WebDriver getting started guide and Python Chrome WebDriver API.
3. Wait for the page state you need
driver.get() navigates to the page, but a site may continue rendering data, images, or widgets afterward. For a dynamic page, wait for a meaningful element rather than assuming a fixed delay is sufficient. For example, wait until a page heading is present:
from pathlib import Path
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
output = Path.home() / "Pictures" / "report.png"
output.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "h1"))
)
driver.save_screenshot(str(output))
print(f"Screenshot saved to {output}")
finally:
driver.quit()
Replace h1 with a selector that indicates the content you intend to capture is ready. A visible heading is only an example: if the important content loads later, wait for that content or for a site-specific condition. A fixed time.sleep() can be useful for a known animation, but it is not a reliable universal page-readiness check.
4. Choose the capture area
Current browser window
driver.save_screenshot("website.png") captures the current window. The visible result depends on the browser window and viewport dimensions. Selenium’s basic screenshot operation does not establish that a tall document will be stitched into one full-page image.
One element
If you need just a chart, card, or other element, locate it and use the element screenshot operation:
from pathlib import Path
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
output = Path.home() / "Pictures" / "chart.png"
output.parent.mkdir(parents=True, exist_ok=True)
driver = webdriver.Chrome()
try:
driver.get("https://example.com")
chart = WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "#chart"))
)
if not chart.screenshot(str(output)):
raise OSError(f"Could not save screenshot to {output}")
print(f"Element screenshot saved to {output}")
finally:
driver.quit()
Change #chart to the target element’s CSS selector. The element must exist and be displayed. See Selenium’s screenshot documentation for window and element capture details.
5. ChromeDriver setup and version compatibility
Start with webdriver.Chrome(). In modern Selenium, Selenium Manager can discover the browser and manage the driver in most supported environments, which means a separate ChromeDriver download is not normally the first step.
Selenium’s Chrome guidance says Selenium 4 is compatible by default with Chrome 75 and later, and Chrome and ChromeDriver should match at the major-version level. If automatic driver setup fails, note your installed Chrome version and any separate chromedriver.exe version. For a manually managed driver, select one according to Google’s Chrome for Testing version information and Selenium’s Chrome-specific documentation. Driver selection can vary by Chrome release, so consult Google’s current version-selection guidance rather than guessing from an old download link.
6. Common errors and fixes
| Symptom | Likely cause | What to do |
|---|---|---|
selenium cannot be imported |
The package was installed into a different Python environment, or the virtual environment is not active. | Activate .venv, or use .\.venv\Scripts\python.exe -m pip install -U selenium and run the script with that same interpreter. |
| Chrome or driver startup fails with a version/session error | A manually installed ChromeDriver may not match Chrome’s major version, or Selenium Manager could not resolve a driver. | Record Chrome, Selenium, and ChromeDriver versions. Remove an unintended stale driver from PATH, retry Selenium Manager, or install the driver matching the Chrome release using Google’s current guidance. |
| Driver download or startup times out | A proxy, firewall, or network policy may prevent Selenium Manager from obtaining driver metadata or a driver. | Check the complete exception text and network policy. In a restricted environment, provision a compatible driver through the approved local process and configure Selenium to use it. |
| Screenshot returns false or the file is missing | The parent directory may not exist, the path may be invalid, or the process may not have write permission. | Create the parent directory, use a raw Windows path such as Path(r"C:\screenshots\page.png"), and confirm the account can write there. |
| Screenshot is blank, incomplete, or missing dynamic content | Capture happened before the relevant page state rendered, or the target is outside the current viewport. | Wait for a meaningful visible element or condition, then capture. Scroll or resize the window if the needed content is not in view; use a dedicated full-page method if the whole document must be represented in one image. |
| Chrome processes remain after the script ends | An exception path may have skipped session cleanup. | Put browser work inside try/finally and call driver.quit() in the finally block. |
When diagnosing startup, keep the full exception text, Selenium package version, Chrome version, any installed ChromeDriver version, and whether a proxy or network restriction applies. These details distinguish setup failures from page-load and file-path problems.
7. Reliability, performance, and cost
- Reliability: Wait for the content that matters, check whether the screenshot save succeeded, and always close the session. The correct readiness condition is site-specific.
- Performance: Each run starts or connects to a browser session and loads the target page. Avoid launching unnecessary sessions in a batch workflow; reuse a session when appropriate, while handling page state and cleanup deliberately.
- Image scope: A current-window shot is bounded by the viewport. Element capture narrows the output to one element. Full-document capture requires a separate approach; do not assume the basic screenshot call stitches the page.
- Cost: Selenium, Chrome, and ChromeDriver are software, and this local workflow has no per-screenshot API charge. Account for the machine resources and maintenance involved in running browsers, especially when scaling automation.
Or skip the browser setup
If you need screenshots without installing or maintaining a browser and driver, ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call API returns an image or PDF; see the API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.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 like a visitor and more than 60 known consent platforms are removed before the shot; newsletter popups and chat widgets are removed too. Each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed. Response headers identify the page verdict and billing status.
- An MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
- The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; every feature is on every plan.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
Does save_screenshot() create a JPEG?
Selenium’s documented screenshot operation saves a PNG. The filename extension should match the PNG output.
Do I have to download ChromeDriver separately?
Usually not with a current Selenium installation: try Selenium Manager through webdriver.Chrome(). Manual driver management is a fallback for environments where automatic resolution is unavailable or unsuitable.
Can I save screenshots somewhere other than Pictures?
Yes. Pass a writable path ending in a PNG filename. Create the parent folder first if it does not exist.
Will this run headlessly?
The example opens Chrome normally. Headless behavior and browser options depend on the Selenium and Chrome versions in use; add and verify the current Chrome headless option for your environment if no visible browser window is desired.


