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 minuteUse Selenium’s modern Python locator API: import By, find the target with driver.find_element(By.ID, "submit"), then call .click(). For a page that renders asynchronously, use an explicit wait—usually element_to_be_clickable—before clicking. find_element returns the first match; find_elements returns a list of matches.
Locate and click a Selenium element
For a control that is already present and ready, locate it by a stable attribute and call its WebElement click() method:
from selenium.webdriver.common.by import By
element = driver.find_element(By.ID, "submit")
element.click()
This uses Selenium’s current Python API: pass a locator strategy from By and its value as two arguments. Older locator-specific methods such as find_element_by_id should not be used in new examples; Selenium’s Python locator guidance described their removal after Selenium 4.2. The official WebDriver API describes the operation as finding an element given a By strategy and locator.
For a dynamic page, wait for the control to become visible and enabled before clicking:
#1 Best Overall
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
button = wait.until(
EC.element_to_be_clickable((By.ID, "submit"))
)
button.click()
The examples assume driver is an initialized WebDriver for the page you want to automate. Replace "submit" with an attribute value that actually identifies the target on that page.
Choose the right locator
Selenium provides several locator strategies. Prefer a specific, stable attribute—an ID when the page has a suitable unique one—over a locator that merely happens to match the current markup.
| Strategy | Good fit | Trade-off |
|---|---|---|
By.ID |
A stable, unique element ID. | Only dependable if the page supplies the ID and it identifies the intended element. |
By.NAME |
A control with a stable name attribute. | May match multiple elements; check the result if uniqueness matters. |
By.CSS_SELECTOR |
Attributes and straightforward element structure. | Long selectors tied to incidental markup can be brittle. |
By.XPATH |
Readable relationships between elements or text-based conditions. | Complex expressions are harder to maintain; anchor them to stable attributes where possible. |
By.CLASS_NAME |
An element identified by a class when that class is sufficiently specific. | Classes are often shared by many elements, so a match may not be unique. |
By.TAG_NAME |
Finding elements by their HTML tag. | Common tags usually match many elements. |
By.LINK_TEXT / By.PARTIAL_LINK_TEXT |
A link whose visible wording is a useful locator. | Copy changes and localization can break text-dependent locators. |
Selenium also lists RelativeBy among its locator options. For ordinary controls, start with the simplest stable locator that identifies the intended target; use a relationship-based or text-based expression only when it makes the target clearer.
Rank #2
CSS selector or XPath?
Use a CSS selector for a concise attribute match or simple structure, for example By.CSS_SELECTOR, "button[data-action='submit']". Use XPath when the relationship or text condition is important and the expression remains readable. Neither is inherently reliable just because of its syntax: a selector coupled to changing layout or copy can fail, while a stable ID or attribute can survive unrelated markup changes.
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 reinstallCrashes, 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 minuteOne match or many?
Use find_element(by, value) when you expect one target. It returns the first matching WebElement, so a locator matching several elements can silently select the wrong one. Use find_elements(by, value) when the page contains repeated cards, rows, links, or controls and you need to examine the collection or choose a particular item deliberately.
from selenium.webdriver.common.by import By
buttons = driver.find_elements(By.CSS_SELECTOR, "button.save")
for button in buttons:
print(button.text)
If the task is to click one particular repeated control, first narrow the set using a distinguishing attribute or context. Do not assume that the first match is the one intended simply because Selenium found it.
Rank #3
Wait for the condition your click needs
A page can contain an element in its DOM before the user can interact with it. Choose an explicit-wait condition that provides the guarantee you need rather than treating presence, visibility, and clickability as interchangeable.
| Wait condition | What it establishes | When it is insufficient |
|---|---|---|
presence_of_element_located |
The element exists in the DOM. | It does not establish that it is visible or enabled. |
visibility_of_element_located |
The element exists and is displayed with height and width greater than zero. | It does not establish that the control is enabled. |
element_to_be_clickable |
The element is visible and enabled; the wait returns the element when this condition is met. | A page-specific overlay or interaction state can still interfere with a click. |
Use an explicit wait for asynchronous pages
Use WebDriverWait when rendering, a transition, or validation may delay readiness. The timeout is the maximum time the wait will keep checking for its condition; it is not a guarantee that the condition will become true. If the condition is not met in time, the wait fails rather than making an unready click reliable.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
submit = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))
)
submit.click()
Choose a condition that matches the next action. If you only need to read an element, visibility may be enough. If you intend to click, waiting for clickability is a better starting point than waiting only for DOM presence.
Rank #4
Handle frames, overlays, and page rerenders
When the element is inside an iframe
Switch WebDriver into the iframe before searching its contents. A locator evaluated in the parent document will not locate a control inside a frame.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID, "payment-frame")))
try:
button = wait.until(
EC.element_to_be_clickable((By.ID, "confirm"))
)
button.click()
finally:
driver.switch_to.default_content()
Replace the frame locator with one that matches the page. Switching back to the default document after frame work prevents a later lookup from accidentally remaining scoped to that frame.
When a click is intercepted
An overlay, transition, or other element may cover the target. Wait for the obstructing state to end and for the intended element to become clickable. A JavaScript-triggered click is not a default substitute: it can bypass the user-like interaction the automation is meant to perform and conceal the actual page problem.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Best Value
When the page rerenders
A rerender can replace an element after Selenium has located it. If a saved WebElement reference becomes stale, locate the element again after the update instead of repeatedly using the old reference. Keep the locator in a variable or helper so reacquiring the current element is straightforward.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common errors and how to recover
- The wrong control was clicked: the locator may match multiple elements, and
find_elementreturns the first. Inspect all matches withfind_elements, then make the locator more specific. - The element could not be found: check that the locator strategy and value match the current page, that the page has reached the relevant state, and that the control is not inside an iframe. Switch into the frame before searching if it is.
- The element is present but not interactable: presence alone does not mean visible or enabled. Wait for visibility or clickability according to the action you need.
- The click is intercepted: identify whether an overlay or transition is covering the target. Wait for that state to clear, then wait for the target to become clickable.
- A previously located element is stale: the page may have rerendered and replaced it. Reacquire the element after the rerender.
- A text-based locator stops working: visible wording may have changed or been localized. Prefer a stable identifying attribute if the application exposes one.
- A locator-specific method is unavailable: use the modern two-argument form, such as
driver.find_element(By.ID, "submit"), rather than legacyfind_element_by_idsyntax.
Make click scripts more reliable
- Choose locators that identify the intended control, not merely a plausible first match.
- Use explicit waits for asynchronous rendering and the state required by the next action.
- Keep XPath and CSS selectors readable and tied to stable attributes rather than incidental page structure.
- After a rerender, reacquire the WebElement instead of assuming an earlier reference remains valid.
- When a click fails, diagnose frame context, visibility, enabled state, overlays, and rerendering before changing the interaction method.
Or skip the browser setup
If your goal is a screenshot rather than interacting with a control, ScreenshotNeo can return a page capture through one GET request. It does not replace Selenium for locating and clicking page elements; it is a separate option when you need an image or PDF of a page.
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,
)
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}`);
See the ScreenshotNeo API documentation for request options. It accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers indicate the page verdict and whether the request was billed. AI agents can use its MCP server tools—take_screenshot, get_page_info, and capture_pdf. The 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 required.
FAQ
Can I use Selenium to click a link as well as a button?
Yes. Locate the link with an appropriate strategy, such as By.LINK_TEXT when its visible wording is stable, then call .click() on the returned WebElement.
Can I locate an element relative to another one?
Selenium includes RelativeBy among its locator options. Use a relative locator when the relationship helps identify the target more clearly than a broad match, and keep the locator anchored to elements that are stable on the page.
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.

