ThisCalculator

Everyday

Python Selenium Locators: How to Use Them

Updated · Standard formula, shown below

This guide explains how to locate web elements in Selenium using Python. You’ll learn the different locator strategies, how to write robust selectors, and how to avoid common pitfalls. By the end, you’ll be able to reliably find elements on a page for your automation scripts.

What You’ll Need

  • Python 3.6 or later installed
  • Selenium installed (pip install selenium)
  • A browser driver (e.g., ChromeDriver for Chrome, GeckoDriver for Firefox) that matches your browser version
  • Basic understanding of HTML and CSS selectors

Step-by-Step

  1. Import Selenium modules
    Start by importing the necessary classes: from selenium import webdriver and from selenium.webdriver.common.by import By. The By class provides the locator type constants like By.ID, By.CLASS_NAME, etc.
  2. Initialize the driver
    Create an instance of the driver for your browser. For Chrome: driver = webdriver.Chrome(). For Firefox: driver = webdriver.Firefox(). Ensure the driver executable is in your PATH or specify its location.
  3. Navigate to a page
    Use driver.get("https://example.com") to load the page where you want to locate elements.
  4. Use the find_element method
    Call driver.find_element(By.ID, "element_id") to find a single element. If you need all matching elements, use find_elements (plural) which returns a list.
  5. Choose a locator strategy
    Selenium offers several locator types. The most common are:
    • By.ID – uses the id attribute. Example: By.ID, "username"
    • By.NAME – uses the name attribute. Example: By.NAME, "password"
    • By.CLASS_NAME – uses a CSS class name. Example: By.CLASS_NAME, "btn-primary"
    • By.TAG_NAME – uses HTML tag. Example: By.TAG_NAME, "a"
    • By.CSS_SELECTOR – uses CSS selector syntax. Example: By.CSS_SELECTOR, "#submit-btn"
    • By.XPATH – uses XPath expression. Example: By.XPATH, "//input[@type='email']"
    • By.LINK_TEXT – matches anchor text exactly. Example: By.LINK_TEXT, "Sign In"
    • By.PARTIAL_LINK_TEXT – matches a substring of anchor text. Example: By.PARTIAL_LINK_TEXT, "Sign"
  6. Interact with the element
    Once you have the element, you can send keys, click, or read text. For example: element.send_keys("myuser") or element.click().
  7. Handle waiting for elements
    To avoid race conditions, use explicit waits. Create a WebDriverWait object and use expected_conditions. Example:
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    wait = WebDriverWait(driver, 10)
    element = wait.until(EC.presence_of_element_located((By.ID, "dynamic")))
  8. Close the driver
    After your script finishes, call driver.quit() to close the browser and free resources.

Common Mistakes

  • Using brittle locators – Relying on absolute XPaths like /html/body/div[2]/form/input[1] breaks when the page structure changes. Prefer IDs, names, or stable CSS selectors.
  • Mixing up find_element and find_elements – find_element returns the first match or raises an exception if none; find_elements returns an empty list if none. Using the wrong one can cause errors or unexpected behavior.
  • Ignoring waits – Trying to locate an element before it appears in the DOM (due to JavaScript loading) leads to NoSuchElementException. Always use explicit waits for dynamic content.
  • Incorrect CSS selector syntax – Forgetting to prefix ID with # or class with . will cause the selector to fail. For example, By.CSS_SELECTOR, "username" looks for a tag named username, not an ID.
  • Not escaping quotes in XPath – If your XPath contains quotes, you need to escape them properly. For example, //button[contains(text(), "Submit")] works, but nested quotes can break.

Tips

  • Prefer By.ID when available – it’s the fastest and most reliable.
  • Use relative XPath (starting with //) instead of absolute paths.
  • Use CSS selectors for complex structures – they are often more readable than XPath.
  • When using By.CLASS_NAME, note that it only accepts a single class name; for multiple classes, use a CSS selector like "class1.class2".
  • Always use WebDriverWait for elements that appear after AJAX calls.
  • Store locators as constants or in a separate file to make maintenance easier.
  • Use find_elements to check if an element exists without raising an exception – if the list is non-empty, it exists.

Troubleshooting

NoSuchElementException – The element wasn’t found. Check the locator string, ensure the element is present in the DOM (maybe it’s inside an iframe – switch to the iframe first), and verify you’re on the correct page.

ElementNotInteractableException – The element exists but is not visible or enabled. Wait for it to become visible using EC.visibility_of_element_located or scroll to it with driver.execute_script("arguments[0].scrollIntoView();", element).

StaleElementReferenceException – The element was found, but the page changed (e.g., after navigation or DOM update). Re-find the element after the change.

TimeoutException – The wait expired. Increase the timeout, or check if the expected condition is correct. Sometimes the element is present but not visible, so use presence_of_element_located instead of visibility_of_element_located.

Multiple elements match – If find_element returns an element you didn’t expect, it’s because your locator is too broad. Refine it to target the specific element, or use find_elements and index the list.

Frequently Asked Questions

Q: What is the difference between find_element and find_elements?
A: find_element returns the first matching element and raises an exception if none is found. find_elements returns a list of all matching elements (empty if none).

Q: Which locator is fastest?
A: ID is generally the fastest because it’s a unique identifier. CSS selectors are also fast. XPath is slower, especially with complex expressions, but still acceptable for most scripts.

Q: Can I use multiple classes in By.CLASS_NAME?
A: No, By.CLASS_NAME only accepts one class name. For multiple classes, use By.CSS_SELECTOR with a dot notation like "class1.class2".

Q: How do I locate an element inside an iframe?
A: First switch to the iframe using driver.switch_to.frame("iframe_id") or by index. After locating the element, switch back with driver.switch_to.default_content().

Q: What is the best way to handle dynamic elements?
A: Use explicit waits with WebDriverWait and expected conditions like EC.element_to_be_clickable or EC.visibility_of_element_located. This ensures the element is ready before interaction.

Q: Can I use a locator to find an element by its text?
A: Yes, use By.XPATH with //tag[text()='exact text'] or contains(text(), 'partial'). For links, By.LINK_TEXT or By.PARTIAL_LINK_TEXT are simpler.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.