Python Selenium Locators: How to Use Them
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
- Import Selenium modules
Start by importing the necessary classes:from selenium import webdriverandfrom selenium.webdriver.common.by import By. TheByclass provides the locator type constants likeBy.ID,By.CLASS_NAME, etc. - 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. - Navigate to a page
Usedriver.get("https://example.com")to load the page where you want to locate elements. - Use the
find_elementmethod
Calldriver.find_element(By.ID, "element_id")to find a single element. If you need all matching elements, usefind_elements(plural) which returns a list. - Choose a locator strategy
Selenium offers several locator types. The most common are:By.ID– uses theidattribute. Example:By.ID, "username"By.NAME– uses thenameattribute. 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"
- Interact with the element
Once you have the element, you can send keys, click, or read text. For example:element.send_keys("myuser")orelement.click(). - Handle waiting for elements
To avoid race conditions, use explicit waits. Create aWebDriverWaitobject and useexpected_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")))
- Close the driver
After your script finishes, calldriver.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_elementandfind_elements–find_elementreturns the first match or raises an exception if none;find_elementsreturns 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 namedusername, 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.IDwhen 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
WebDriverWaitfor elements that appear after AJAX calls. - Store locators as constants or in a separate file to make maintenance easier.
- Use
find_elementsto 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.