Web interfaces often identify controls through nearby labels, ancestor sections, or visible text instead of one unique attribute. XPath gives Selenium a way to express those relationships and distinguish one control from visually similar controls elsewhere on the page.
Python passes an XPath expression through By.XPATH to find_element() or an explicit-wait locator tuple. A lookup from the driver searches the current document, while a lookup from an existing WebElement can stay within that element when the expression starts with .//.
Prefer a stable unique ID or CSS selector when either describes the target directly. Reserve XPath for relationships that belong to the interface contract, and avoid copied absolute paths or positional indexes that break when a wrapper or neighboring component changes.
FORM = (By.XPATH, "//form[.//input[@name='my-text']]") FIELD_XPATH = ".//input[@name='my-text']" BUTTON_XPATH = ".//button[normalize-space()='Submit']"
The form locator requires a descendant input named my-text. normalize-space() ignores extra whitespace around the visible button label.
form = WebDriverWait(driver, 10).until( EC.presence_of_element_located(FORM) )
The explicit wait retries the locator until the form exists or the timeout raises an exception.
Related: How to use explicit waits in Selenium
field = form.find_element(By.XPATH, FIELD_XPATH)
The leading dot in .// keeps the search inside form. A bare // expression starts from the document root and can select a matching control from another form.
button = form.find_element(By.XPATH, BUTTON_XPATH)
assert ( form.tag_name, field.get_dom_attribute("name"), button.text, ) == ("form", "my-text", "Submit")
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait URL = "https://www.selenium.dev/selenium/web/web-form.html" FORM = (By.XPATH, "//form[.//input[@name='my-text']]") FIELD_XPATH = ".//input[@name='my-text']" BUTTON_XPATH = ".//button[normalize-space()='Submit']" driver = webdriver.Chrome() try: driver.get(URL) form = WebDriverWait(driver, 10).until( EC.presence_of_element_located(FORM) ) field = form.find_element(By.XPATH, FIELD_XPATH) button = form.find_element(By.XPATH, BUTTON_XPATH) assert ( form.tag_name, field.get_dom_attribute("name"), button.text, ) == ("form", "my-text", "Submit") print(f"page_title: {driver.title}") print(f"form_tag: {form.tag_name}") print(f"field_name: {field.get_dom_attribute('name')}") print(f"button_text: {button.text}") finally: driver.quit()
$ python3 selenium-find-xpath.py page_title: Web form form_tag: form field_name: my-text button_text: Submit