The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Use Selenium 4’s ChromeOptions and add Chrome’s --headless=new argument. Pass the options object to webdriver.Chrome, wait for dynamic content when necessary, and always call driver.quit() in a finally block.
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
This starts Chrome without displaying a normal browser window. The rest of this guide covers installation, driver versions, waits, viewport control, CI troubleshooting, and an API alternative when you do not need to manage a browser process yourself.
What background (headless) Chrome means
Headless Chrome runs the browser engine without opening a visible desktop window. Selenium still creates a normal WebDriver session: it can navigate, execute JavaScript, find elements, take screenshots, and interact with pages. Only the displayed window is omitted.
For current Selenium Python bindings, use the Chromium argument --headless=new. Older examples that assign options.headless = True are not the current recommended form; Selenium’s guidance says that property form was removed.
#1 Best Overall
Install Selenium and prepare Chrome
Install the Python package
Install Selenium into the same Python environment that will run your script:
python -m pip install selenium
Selenium ships with Selenium Manager, the official driver manager of the Selenium project. When a driver is not already available, the Selenium bindings can invoke Selenium Manager to discover, download, and cache a compatible driver. In supported configurations it can also manage Chrome browser downloads.
Check the environment before running
- A Chrome or Chromium installation must be available, or Selenium Manager must be allowed to download a browser in the configuration you use.
- The first driver or browser resolution may require outbound network access. Proxies, offline workers, and restricted CI networks can prevent it.
- Linux containers need the browser’s required system libraries. The headless flag does not install operating-system dependencies.
- If Chrome is installed in a nonstandard location, configure its binary path explicitly.
Keep the Selenium package, browser, and driver version policy consistent across development and deployment. Selenium Manager supports configuration through command-line options, a se-config.toml file, and environment variables, including browser-version selection.
Run a minimal headless script
The following complete program opens a page, prints its title, and closes Chrome whether navigation succeeds or raises an exception:
Recommended Free Tools
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
# Set this when layout or screenshots must be repeatable.
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
ChromeOptions.add_argument() is the Python API for adding Chrome command-line arguments. The window-size line is optional: omit it to let Chrome use its normal headless default, or set it when responsive breakpoints and image dimensions matter.
Wait for pages that render after navigation
driver.get() does not guarantee that a JavaScript application has finished fetching and rendering every component. Use an explicit wait tied to the state you need instead of relying on a guessed sleep duration.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1440,1000")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com/dashboard")
panel = WebDriverWait(driver, 20).until(
EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-testid='dashboard']"))
)
print(panel.text)
finally:
driver.quit()
Choose a selector or state that represents usable content: an element becoming visible, a loading indicator disappearing, or a specific title or URL. A fixed delay can be useful for a known animation, but it is less reliable when network speed varies.
Rank #2
Choose a predictable viewport
Headless mode and viewport size are separate settings. Add --window-size=WIDTH,HEIGHT when you need deterministic responsive behavior, screenshots, or visual comparisons:
Free tools Windows power users keep installed
One-click scans. No signup required.
options.add_argument("--window-size=1440,1000")
A fixed desktop viewport may cause a mobile breakpoint to remain untested. For responsive testing, create separate sessions with representative dimensions rather than assuming one size covers every layout:
for width, height in [(390, 844), (768, 1024), (1440, 1000)]:
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument(f"--window-size={width},{height}")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
print(width, driver.title)
finally:
driver.quit()
Let Selenium Manager handle the driver, or pin it yourself
Default: Selenium Manager
webdriver.Chrome(options=options) is usually sufficient. Selenium invokes its bundled Selenium Manager when it cannot find a usable driver. This avoids adding a separate driver-manager package and reduces manual downloads, but the initial resolution may need network and proxy access.
Manual driver with Service
Use Selenium 4’s Service object when your organization pins an executable, stores drivers in a controlled directory, or runs without download access:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
service = Service("/path/to/chromedriver")
driver = webdriver.Chrome(service=service, options=options)
try:
driver.get("https://example.com")
print(driver.title)
finally:
driver.quit()
Do not use the removed executable_path constructor argument. Chrome and ChromeDriver should have matching major versions. If Chrome updates and a manually installed driver stops working, verify both versions or remove the stale executable and let Selenium Manager resolve a match.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Select an alternate Chrome binary
Leave the binary unset when Chrome is installed conventionally. For a custom installation, set the binary location before creating the driver:
options = webdriver.ChromeOptions()
options.binary_location = "/opt/chrome/chrome"
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
The path must point to an actual Chrome or Chromium binary visible to the process. A driver path and a browser binary path solve different problems: Service selects the driver executable, while binary_location selects the browser.
Control how long navigation waits
Selenium’s page-load strategy determines when navigation returns:
| Strategy | Returns after | Use when | Risk |
|---|---|---|---|
normal (default) |
The load event | You want the conservative default | It can wait longer than a single-page app’s useful content requires |
eager |
DOMContentLoaded | You have explicit waits for application content | Images and other resources may still be loading |
none |
The initial page download | You manage every readiness condition yourself | Interactions can be flaky without robust waits |
Set a strategy through capabilities only when you have matching waits:
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.page_load_strategy = "eager"
driver = webdriver.Chrome(options=options)
For most scripts, keep normal and add explicit waits. Faster strategies are useful for specialized workflows, not as a substitute for knowing when the page is ready.
Use cleanup that survives failures
Always put driver.quit() in finally. It closes the WebDriver session and prevents browser processes from accumulating when navigation, element lookup, or application code fails.
driver = webdriver.Chrome(options=options)
try:
# navigation and test work
pass
finally:
driver.quit()
If you create several drivers in a loop, close each one before creating the next unless you intentionally need concurrent sessions. Reusing one session is generally cheaper than starting a new browser for every URL, while separate sessions provide isolation for cookies, local storage, and viewport settings.
Run headless Chrome in CI or a container
Confirm browser availability
Check that the image contains Chrome or Chromium, or that Selenium Manager is permitted to download it. A minimal Python installation alone is not enough.
Allow resolution traffic
On the first run, Selenium Manager may need to contact remote endpoints to discover and download a driver or browser. Configure the CI proxy and certificate policy, or preinstall and pin the required assets for an offline worker.
Check native dependencies
Container failures can come from missing shared libraries, fonts, or other OS packages. These vary by Linux distribution and image. Diagnose the container’s browser-startup error rather than adding unrelated Chrome flags automatically.
Be cautious with broad flags
Some examples add --no-sandbox. The basic headless workflow does not require it. Add such a flag only when your runtime specifically needs it and your security policy accepts the trade-off.
Troubleshoot common failures
Chrome fails to start
Verify that Chrome is installed or that browser management is enabled, then check the container’s system libraries, executable permissions, and available network access. A headless argument cannot fix a missing binary or dependency.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Fix the driver behind crashes, sound loss and screen glitches3Repair Windows errors before they cause bigger problems“This version of ChromeDriver only supports Chrome version …”
The driver and browser major versions do not match. Remove the stale manually installed driver and let Selenium Manager resolve one, or install a driver whose major version matches Chrome and pass it through Service.
A visible window still appears
Confirm that the exact options object passed to webdriver.Chrome(options=options) contains options.add_argument("--headless=new"). Setting an unused options object, or relying on the removed options.headless property, has no effect.
Browser processes remain after the script exits
Ensure every code path reaches driver.quit(), preferably through finally. Also check that an exception is not terminating the process before the driver is assigned; initialize and clean up each session in a controlled scope.
An element is intermittently missing
Navigation completion may precede application rendering. Add an explicit wait for the element or state you actually need, increase the timeout only when the page legitimately takes longer, and verify that the selector is stable.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteBest Value
Selenium Manager cannot resolve a driver
Check outbound network and proxy access, custom browser locations, offline policy, and stale driver files. If downloads are prohibited, install a compatible browser and driver in the image and configure their paths explicitly.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
If your goal is a rendered screenshot or PDF rather than browser automation, ScreenshotNeo provides a single HTTP request. It accepts consent banners like a visitor, removes more than 60 known consent platforms plus newsletter popups and chat widgets before capture, and lets you turn each cleanup step off. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with the result identified by X-Page-Verdict and X-Billed headers.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.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://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);
See the ScreenshotNeo API documentation for request options. The service also offers an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Features include full-page and element capture, device presets, custom viewport and retina scale, PDF paper settings, custom CSS and JavaScript, clicks, selector waits, network-idle waits, request blocking, cookies, headers, authorization, timezone and geolocation, transparent backgrounds, resizing, TTL caching, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to try it without adding a card.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently Asked Questions
Can I run headless Chrome and still inspect the DOM?
Yes. Headless mode removes the visible window, not the WebDriver or JavaScript environment. You can read page source, locate elements, execute scripts, and collect console or network diagnostics using Selenium APIs.
Should I use Chrome or Chromium with Selenium?
Either can work when the browser binary and matching driver are available. If the executable is nonstandard, set options.binary_location; otherwise let Selenium discover the installed browser.
Is a fixed window size required for headless mode?
No. --window-size is optional. Add it only when you need repeatable responsive layout, screenshots, or viewport-dependent behavior.
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.

