Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchSome links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Use ChromeOptions with --headless=new, create a ChromeDriver session, navigate, and locate elements with Selenium’s current locator API. In Python, the essential call is driver.find_element(By.ID, "submit"). Reliable scripts also choose stable locators, wait for the condition the next action needs, keep Chrome and ChromeDriver major versions aligned, and call quit() when finished.
Working Python example
The following script starts Chrome without a visible window, opens a page, waits for a button to become clickable, finds it with the current API, and tears down the entire browser session.
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")
# Selenium Manager can locate a compatible driver in current Selenium releases.
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
wait = WebDriverWait(driver, 15)
heading = wait.until(
EC.visibility_of_element_located((By.TAG_NAME, "h1"))
)
print(heading.text)
finally:
driver.quit()
Install Selenium with python -m pip install selenium. Replace the example URL and locator with the page under test. The explicit wait is intentional: a completed navigation does not guarantee that JavaScript has created or revealed the element you need.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Configure Chrome for headless execution
Use ChromeOptions
Create the binding’s ChromeOptions object, add the browser argument --headless=new, and pass the options to ChromeDriver. Headless is a browser argument, not a different Selenium locator API. Current Selenium Chrome guidance uses this options-based pattern.
#1 Best Overall
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.add_argument("--window-size=1280,900")
driver = webdriver.Chrome(options=options)
A window-size argument is useful when responsive CSS changes which elements exist or whether they are visible. If Chromium is installed outside the default location, configure the options object with that browser’s binary path according to your binding’s documentation.
Use the right headless switch for your environment
Selenium’s older convenience headless method was removed in Selenium 4.10.0 so users could select a mode. Current Chrome-specific guidance identifies --headless=new. If an older Selenium or Chrome installation rejects the argument, check the versions actually installed and use the option documented for that combination rather than copying an obsolete helper call.
Find an element with the current API
Python syntax
Import By and pass a strategy plus locator value:
from selenium.webdriver.common.by import By
submit = driver.find_element(By.ID, "submit")
submit.click()
The old helpers such as find_element_by_id are not the current Python interface. find_element returns the first matching element and raises an error when no match exists. Use find_elements when zero matches are a valid result; it returns a list, which may be empty.
Rank #2
Supported strategies
| Strategy | Example | When to use it |
|---|---|---|
| ID | By.ID, "submit" |
A stable unique id is usually the clearest choice. |
| Name | By.NAME, "email" |
Useful for stable form controls. |
| CSS selector | By.CSS_SELECTOR, "[data-test='submit']" |
Prefer a dedicated, stable attribute such as data-test. |
| XPath | By.XPATH, "//button[@type='submit']" |
Helpful when a relationship or text condition cannot be expressed simply in CSS. |
| Class name | By.CLASS_NAME, "primary" |
Only when the class is an intentional stable hook. |
| Tag name | By.TAG_NAME, "h1" |
Useful when the page has a single meaningful tag. |
| Link text | By.LINK_TEXT, "Documentation" |
For an exact anchor label. |
| Partial link text | By.PARTIAL_LINK_TEXT, "Doc" |
For a deliberately partial anchor label. |
Prefer a stable ID or name, then a CSS selector using a dedicated attribute. Absolute XPath (for example, a full /html/body/... path) and generated class names are brittle because small markup or build changes invalidate them. Relative locators are also available in current Selenium bindings when spatial relationships are the most useful description.
Wait for the state your next command needs
Why navigation is not enough
Navigation waits according to the session’s page-load strategy, but that readiness covers document resources. Client-side code can still insert, replace, or reveal the target afterward. A returned get() call therefore does not prove that an element is present or interactable.
Explicit waits
Choose a condition that matches the next operation:
Rank #3
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 20)
# Exists in the DOM:
card = wait.until(EC.presence_of_element_located(
(By.CSS_SELECTOR, "[data-test='result']")
))
# Has been rendered and visible:
search = wait.until(EC.visibility_of_element_located(
(By.NAME, "q")
))
# Can receive the interaction:
button = wait.until(EC.element_to_be_clickable(
(By.ID, "submit")
))
button.click()
Use a delay only when you have no more precise condition. Waiting for a selector or state makes failures faster and explains what was missing.
Implicit, explicit, and page-load waits
A new session’s implicit element-location timeout defaults to zero. Do not combine implicit and explicit waits in the same session: their polling behavior can compound timeouts and make failures difficult to predict.
Selenium provides three page-load strategies:
| Strategy | Navigation waits for | Trade-off |
|---|---|---|
normal |
The load event and associated resources | Most waiting before the call returns; JavaScript may still change the page. |
eager |
DOMContentLoaded | Returns earlier, so subsequent explicit waits must cover more application work. |
none |
The initial page download | Fastest return, but every required condition must be waited for explicitly. |
options = webdriver.ChromeOptions()
options.add_argument("--headless=new")
options.page_load_strategy = "eager"
driver = webdriver.Chrome(options=options)
Changing this setting affects the whole session. Pick the strategy for your application and retain explicit waits for the actual state each test needs.
Rank #4
Diagnose “no such element” in headless Chrome
- Confirm the active page. Print
driver.current_urland inspect the title or saved page source. A redirect, authentication page, or error document may be active instead of the intended URL. - Check the markup and locator. Verify the ID, name, attribute, or text in the current DOM. Replace generated classes and absolute XPath with a stable hook where possible.
- Check timing. If a client-side framework creates the element after navigation, add an explicit wait for presence, visibility, or clickability.
- Check the browsing context. If the element belongs to a frame, the intended frame must be active before lookup; inspect the page structure and switch context using your binding’s documented frame API.
- Check headless-specific layout. Set a representative window size and verify that responsive rules have not hidden or replaced the control.
- Check the browser session itself. If ChromeDriver cannot create a session, investigate browser and driver compatibility before changing locators.
Common startup errors
| Symptom | Likely cause | Fix |
|---|---|---|
| Session fails before the first page loads | Chrome and ChromeDriver major versions do not match, or the browser binary is not where the driver expects. | Check both installed versions, align their major versions, and set the binary location when using a non-default Chromium installation. |
find_element raises immediately |
The element is absent at lookup time. | Verify the current URL and DOM, then wait for the required condition. |
| Element exists but click fails | It is present but not visible or interactable. | Wait for visibility or clickability and check overlays or responsive layout. |
| Intermittent failures | A race between navigation or JavaScript rendering and the lookup. | Use one consistent explicit-wait strategy; remove arbitrary sleeps and do not mix implicit waits. |
Version and teardown checklist
- Use Selenium 4-compatible code with a ChromeOptions object.
- Pass
--headless=newas a Chrome argument. - Keep Chrome and ChromeDriver major versions aligned; Selenium’s Chrome documentation describes Selenium 4 compatibility with Chrome v75 and later.
- Use
find_element(By.<strategy>, locator), not removed Python convenience methods. - Choose stable IDs, names, or test attributes.
- Wait for the condition required by the next command.
- Call
driver.quit()in cleanup;close()only closes a window and is not the recommended session teardown.
Or skip the browser setup
If your goal is a clean screenshot rather than browser interaction, ScreenshotNeo provides a single HTTP request. It accepts cookie and consent banners as a visitor, then removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be disabled. Only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
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 all options, including PNG, JPEG, WebP, PDF, full-page capture, custom waits, selectors, headers, cookies, device presets, and asynchronous jobs.
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}`);
The Free plan includes 1,000 screenshots each 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.
FAQ
What does find_elements return when nothing matches?
It returns an empty list. Use it when zero matches is expected; use find_element when one match is required and a missing element should fail the operation.
Best Value
Can I use headless mode with a non-default Chromium browser?
Yes, when your Selenium binding supports a browser binary option. Set the ChromeOptions binary location to the installed executable and verify that the corresponding driver major version is compatible.
Which wait should I use for a button?
Wait for clickability when the next operation is a click. Presence only proves that an element is in the DOM; visibility proves it is rendered, not necessarily ready to receive the interaction.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Frequently Asked Questions
What does find_elements return when nothing matches?
It returns an empty list; use find_element when a missing match should raise an error.
Can headless Selenium run with a non-default Chromium binary?
Yes. Set the browser binary through ChromeOptions and keep the browser and driver major versions compatible.
Which wait is appropriate before clicking a button?
Use an explicit wait for clickability; presence alone only confirms that the element is in the DOM.
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.

