Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

Use Selenium’s current Python locator syntax, driver.find_element(By.ID, "submit"), then call .click(). For a page that renders or enables the control asynchronously, wait for the condition you actually need—usually element_to_be_clickable—before clicking. The examples below show how to choose a locator, distinguish a single match from multiple matches, and diagnose common failures.

Locate and click a control

Import By from Selenium’s locator module, pass a locator strategy and value to find_element, then call click() on the returned WebElement:

from selenium.webdriver.common.by import By

button = driver.find_element(By.ID, "submit")
button.click()

This short version is suitable when the page is already loaded and the target is present and ready to interact with. For a dynamic page, use an explicit wait instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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 locator passed to the wait is a tuple: the strategy, followed by its value. The wait returns the matching element once the condition is met, so the returned WebElement can be clicked directly.

Complete example

This script opens a page, waits for an element whose ID is submit to become clickable, clicks it, and closes the browser even if a step raises an exception. Replace the example URL and locator with the ones for your page. It assumes Selenium is installed and a compatible Chrome browser and driver setup is available.

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

url = "https://example.com"
driver = webdriver.Chrome()

try:
    driver.get(url)
    wait = WebDriverWait(driver, 10)
    button = wait.until(
        EC.element_to_be_clickable((By.ID, "submit"))
    )
    button.click()
finally:
    driver.quit()

Choose the locator that identifies the right element

Selenium supports several locator strategies through By. The best one is not necessarily the shortest: it should identify the intended control clearly and remain stable as the page changes.

Strategy Example Useful when Trade-off
By.ID (By.ID, "submit") The page gives the control a unique, stable ID. Only dependable if the ID is present and unique in the relevant page context.
By.NAME (By.NAME, "email") A form control has a meaningful name attribute. Several controls can share a name, so check whether the match is unique.
By.CSS_SELECTOR (By.CSS_SELECTOR, "button[type='submit']") You need to match attributes, classes, or simple element structure concisely. A long selector tied to incidental page structure can be hard to maintain.
By.XPATH (By.XPATH, "//button[@type='submit']") You need a relationship between elements or a text-based condition. Complex expressions are harder to read and can become brittle when the DOM changes.
By.CLASS_NAME (By.CLASS_NAME, "primary") A useful class identifies the target. Classes are often shared among many elements; this may return the wrong first match.
By.TAG_NAME (By.TAG_NAME, "button") You intend to inspect or collect elements by HTML tag. Usually too broad for locating one specific control on a page.
By.LINK_TEXT / By.PARTIAL_LINK_TEXT (By.LINK_TEXT, "Continue") A link’s visible wording is a useful identifier. Copy edits, localization, or repeated link labels can make the match fail or become ambiguous.

Selenium also documents RelativeBy for relative element location. For ordinary click scripts, start with a stable unique attribute such as an ID when the application provides one. Use CSS for straightforward attribute and structure matches; choose XPath when a relationship or text condition genuinely helps. Keep either expression readable and anchored to meaningful attributes rather than a fragile chain of containers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

CSS selector and XPath examples

# CSS: a submit button
button = driver.find_element(
    By.CSS_SELECTOR, "button[type='submit']"
)

# XPath: a button with a specific accessible page label
button = driver.find_element(
    By.XPATH, "//button[normalize-space()='Continue']"
)

button.click()

Text-based lookup is convenient when the visible wording is distinctive, but it couples the script to that wording. For sites with multiple languages or frequently edited copy, a stable ID, name, or data attribute is usually a better anchor if available.

find_element versus find_elements

find_element(by, value) returns the first matching WebElement. Use it when your locator is intended to find one control. If there is no match, Selenium raises an exception rather than returning an empty value.

find_elements(by, value) returns a list of every matching WebElement; if there are no matches, the result is an empty list. Use it for repeated cards, rows, links, or controls, and make a deliberate choice instead of assuming the first item is the one you want.

buttons = driver.find_elements(By.CSS_SELECTOR, "button.action")

if not buttons:
    raise RuntimeError("No action buttons were found")

# Click a chosen match only after confirming the selection rule.
buttons[0].click()

Indexing the first result is appropriate only when page order is itself a reliable selection rule. If the target has a distinguishing attribute or nearby context, narrow the locator rather than relying on list order.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Wait for the guarantee your click needs

A page can contain an element before it is visible or enabled. Choose an explicit-wait condition according to the state required for the next action:

Condition What it establishes When to use it
presence_of_element_located The element exists in the DOM. When the next step only needs DOM presence; it does not establish visibility.
visibility_of_element_located The element exists and is displayed with height and width greater than zero. When the next step needs a visible target, but does not require that it be enabled.
element_to_be_clickable The element is visible and enabled, and the wait returns it. For a typical user-like click on a control that may appear or become enabled after rendering or validation.

For example, use presence when waiting for a hidden element that a later step will inspect; use visibility when it must be displayed; use clickability when you intend to click. A presence wait alone does not mean the target is ready for a user-like interaction.

wait = WebDriverWait(driver, 10)

# Wait for a result panel to be inserted in the DOM.
panel = wait.until(
    EC.presence_of_element_located((By.ID, "results"))
)

# Wait for a control to be displayed and enabled before clicking.
button = wait.until(
    EC.element_to_be_clickable((By.ID, "submit"))
)
button.click()

Use an explicit wait when asynchronous rendering, a transition, or form validation determines when the target is ready. Pick a timeout appropriate to the application and environment; an explicit wait is a maximum wait, not a reason to pause for the full interval when its condition succeeds sooner.

Use the current Selenium Python API

Use driver.find_element(By.ID, "submit"), with By imported from selenium.webdriver.common.by. Older examples may show locator-specific calls such as find_element_by_id; Selenium’s Python guidance says those methods were being removed after Selenium 4.2. New scripts should use the By-based form rather than copy that older syntax.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Troubleshoot a click that fails

  • No element found: Check the locator spelling and whether the page has reached the state where the element exists. If rendering is asynchronous, wait for presence or a stronger condition instead of looking up the element immediately.
  • The wrong element was selected: Check whether the locator matches multiple controls. Use a more specific stable attribute, or retrieve all matches with find_elements and apply an explicit selection rule.
  • The element exists but is not usable: A presence check does not guarantee visibility or enabled state. Wait for visibility or clickability according to the action you need.
  • Click intercepted by an overlay: A modal, banner, or other overlay may be covering the target. Wait for the overlay to disappear and then wait for the target to become clickable. Do not make JavaScript click the default workaround; it bypasses the normal user-like interaction and can conceal the actual page state.
  • Element is inside an iframe: Switch WebDriver into the relevant frame before locating the element. After the interaction, switch back to the default content when subsequent work belongs to the main page.
  • Stale element reference after a rerender: The DOM node you stored may have been replaced. Locate the element again after the rerender, then act on the fresh WebElement.
  • Wait times out: Confirm that the locator is correct in the current frame and that the expected state can actually occur. If the control remains disabled until a field is valid, meet that prerequisite before waiting for clickability.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

Selenium is the right fit when you need to interact with a page, including clicking a control. If your actual goal is only to save a page image or PDF, a screenshot API can avoid setting up a browser and WebDriver. ScreenshotNeo is a website screenshot API and MCP server, not a replacement for Selenium clicks. Its one-call endpoint returns a PNG, JPEG, WebP, or PDF screenshot for a URL.

Python example, following the ScreenshotNeo API documentation:

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)

Equivalent cURL call:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Node.js example:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo accepts a cookie or consent banner as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots. See ScreenshotNeo for the service and sign up for the free plan.

Frequently Asked Questions

Does click() wait for the page’s next navigation to finish?

Not necessarily. A successful click means Selenium issued the element interaction; it does not by itself confirm that the application reached the result you expect. For navigation or an in-page update, wait for a page-specific outcome such as the destination URL or a result element before continuing.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Should I use JavaScript to click when Selenium reports an intercepted click?

Not as the first fix. An intercepted click usually indicates the target is covered or not yet in the expected state. Resolve the overlay or timing issue and retry a normal WebElement click; JavaScript can bypass behavior that the script should be testing.

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.