Python bindings for Selenium WebDriver providing automated browser control for multiple browsers including Chrome, Firefox, Edge, Safari, and Internet Explorer
—
This document covers element finding strategies and interaction methods in Python Selenium WebDriver. It includes locator strategies, WebElement methods, and best practices for element interaction.
The By class provides constants for different element locating strategies.
{ .api }
from selenium.webdriver.common.by import By
class By:
ID = "id"
XPATH = "xpath"
LINK_TEXT = "link text"
PARTIAL_LINK_TEXT = "partial link text"
NAME = "name"
TAG_NAME = "tag name"
CLASS_NAME = "class name"
CSS_SELECTOR = "css selector"Description: Set of supported locator strategies for finding elements.
Locator Types:
ID: Select element by its ID attributeXPATH: Select element via XPath expressionLINK_TEXT: Select link element by exact text contentPARTIAL_LINK_TEXT: Select link element by partial text contentNAME: Select element by name attributeTAG_NAME: Select element by tag nameCLASS_NAME: Select element by class nameCSS_SELECTOR: Select element by CSS selectorCustom Finders:
{ .api }
@classmethod
def register_custom_finder(cls, name: str, strategy: str) -> NoneDescription: Register a custom finder strategy.
Parameters:
name: Name of the custom finderstrategy: Strategy string for the finder{ .api }
@classmethod
def get_finder(cls, name: str) -> Optional[str]Description: Get a finder strategy by name.
Parameters:
name: Name of the finderReturns: Strategy string or None if not found
{ .api }
@classmethod
def clear_custom_finders(cls) -> NoneDescription: Clear all custom finders.
{ .api }
def find_element(self, by: str = By.ID, value: Optional[str] = None) -> WebElementDescription: Find an element given a By strategy and locator.
Parameters:
by: The locating strategy to use (default: By.ID)value: The locator valueReturns: WebElement object
Raises: NoSuchElementException if element is not found
Supported locator strategies:
By.ID: Locate by element IDBy.NAME: Locate by the name attributeBy.XPATH: Locate by an XPath expressionBy.CSS_SELECTOR: Locate by a CSS selectorBy.CLASS_NAME: Locate by class nameBy.TAG_NAME: Locate by tag nameBy.LINK_TEXT: Locate by exact link textBy.PARTIAL_LINK_TEXT: Locate by partial link textExamples:
from selenium.webdriver.common.by import By
# Find by ID
element = driver.find_element(By.ID, "myElement")
# Find by XPath
element = driver.find_element(By.XPATH, "//div[@class='container']")
# Find by CSS selector
element = driver.find_element(By.CSS_SELECTOR, ".btn.btn-primary")
# Find by class name
element = driver.find_element(By.CLASS_NAME, "header")
# Find by tag name
element = driver.find_element(By.TAG_NAME, "h1")
# Find by name attribute
element = driver.find_element(By.NAME, "username")
# Find by link text
element = driver.find_element(By.LINK_TEXT, "Click Here")
# Find by partial link text
element = driver.find_element(By.PARTIAL_LINK_TEXT, "Click"){ .api }
def find_elements(self, by: str = By.ID, value: Optional[str] = None) -> List[WebElement]Description: Find elements given a By strategy and locator.
Parameters:
by: The locating strategy to use (default: By.ID)value: The locator valueReturns: List of WebElement objects (empty list if no elements found)
Examples:
# Find all elements with a class
elements = driver.find_elements(By.CLASS_NAME, "item")
# Find all links
links = driver.find_elements(By.TAG_NAME, "a")
# Find all elements matching XPath
items = driver.find_elements(By.XPATH, "//div[contains(@class, 'product')]"){ .api }
from selenium.webdriver.remote.webelement import WebElement
class WebElement(BaseWebElement):
def __init__(self, parent, id_: str) -> NoneDescription: Represents a DOM element. Generally, all interesting operations that interact with a document will be performed through this interface.
Parameters:
parent: The WebDriver instance that found this elementid_: The element ID from the WebDriver protocol{ .api }
@property
def tag_name(self) -> strDescription: This element's tagName property.
Returns: The tag name of the element
Example:
element = driver.find_element(By.ID, 'foo')
print(element.tag_name) # e.g., "div", "input", "a"{ .api }
@property
def text(self) -> strDescription: The text of the element.
Returns: The visible text of the element
Example:
element = driver.find_element(By.ID, 'content')
print(element.text) # Visible text content{ .api }
@property
def size(self) -> dictDescription: The size of the element.
Returns: Dictionary with 'width' and 'height' keys
Example:
element = driver.find_element(By.ID, 'banner')
size = element.size
print(f"Width: {size['width']}, Height: {size['height']}"){ .api }
@property
def location(self) -> dictDescription: The location of the element in the renderable canvas.
Returns: Dictionary with 'x' and 'y' keys
Example:
element = driver.find_element(By.ID, 'button')
location = element.location
print(f"X: {location['x']}, Y: {location['y']}"){ .api }
@property
def rect(self) -> dictDescription: A dictionary with the size and location of the element.
Returns: Dictionary with 'x', 'y', 'width', and 'height' keys
Example:
element = driver.find_element(By.ID, 'modal')
rect = element.rect
print(f"Position: ({rect['x']}, {rect['y']})")
print(f"Size: {rect['width']} x {rect['height']}"){ .api }
def click(self) -> NoneDescription: Clicks the element.
Example:
button = driver.find_element(By.ID, 'submit-btn')
button.click(){ .api }
def clear(self) -> NoneDescription: Clears the text if it's a text entry element.
Example:
text_field = driver.find_element(By.NAME, 'username')
text_field.clear(){ .api }
def send_keys(self, *value: str) -> NoneDescription: Simulates typing into the element.
Parameters:
*value: A string to send, or key combinations using Keys classExample:
from selenium.webdriver.common.keys import Keys
text_field = driver.find_element(By.NAME, 'search')
text_field.send_keys('Python Selenium')
text_field.send_keys(Keys.ENTER)
# Clear and type new text
text_field.send_keys(Keys.CONTROL + 'a') # Select all
text_field.send_keys(Keys.DELETE) # Delete
text_field.send_keys('New text'){ .api }
def submit(self) -> NoneDescription: Submits a form. If this element is a form, or an element within a form, this will submit that form.
Example:
form = driver.find_element(By.TAG_NAME, 'form')
form.submit()
# Or submit via any element within the form
input_field = driver.find_element(By.NAME, 'username')
input_field.submit(){ .api }
def is_selected(self) -> boolDescription: Returns whether the element is selected (for checkboxes, radio buttons, and select options).
Returns: True if element is selected, False otherwise
Example:
checkbox = driver.find_element(By.ID, 'agree-terms')
if checkbox.is_selected():
print("Checkbox is checked")
else:
checkbox.click() # Check the checkbox{ .api }
def is_enabled(self) -> boolDescription: Returns whether the element is enabled.
Returns: True if element is enabled, False otherwise
Example:
submit_btn = driver.find_element(By.ID, 'submit')
if submit_btn.is_enabled():
submit_btn.click()
else:
print("Submit button is disabled"){ .api }
def is_displayed(self) -> boolDescription: Returns whether the element is visible to a user.
Returns: True if element is displayed, False otherwise
Example:
modal = driver.find_element(By.ID, 'error-modal')
if modal.is_displayed():
print("Error modal is visible")
close_btn = modal.find_element(By.CLASS_NAME, 'close')
close_btn.click(){ .api }
def get_attribute(self, name: str) -> Optional[str]Description: Gets the given attribute or property of the element.
Parameters:
name: Name of the attribute/property to retrieveReturns: The value of the attribute/property, or None if not set
Example:
link = driver.find_element(By.TAG_NAME, 'a')
href = link.get_attribute('href')
class_name = link.get_attribute('class')
data_value = link.get_attribute('data-value'){ .api }
def get_dom_attribute(self, name: str) -> strDescription: Gets the given attribute of the element from the DOM.
Parameters:
name: Name of the attribute to retrieveReturns: The attribute value
Example:
element = driver.find_element(By.ID, 'custom-element')
custom_attr = element.get_dom_attribute('data-custom'){ .api }
def get_property(self, name: str) -> Union[str, bool, WebElement, dict]Description: Gets the given property of the element.
Parameters:
name: Name of the property to retrieveReturns: The property value
Example:
input_field = driver.find_element(By.NAME, 'email')
value = input_field.get_property('value')
checked = checkbox.get_property('checked') # Returns boolean{ .api }
def value_of_css_property(self, property_name: str) -> strDescription: The value of a CSS property.
Parameters:
property_name: CSS property nameReturns: The value of the CSS property
Example:
element = driver.find_element(By.ID, 'header')
color = element.value_of_css_property('color')
background = element.value_of_css_property('background-color')
font_size = element.value_of_css_property('font-size'){ .api }
def screenshot_as_base64(self) -> strDescription: Gets the screenshot of the current element as a base64 encoded string.
Returns: Base64 encoded string of the PNG image
{ .api }
def screenshot_as_png(self) -> bytesDescription: Gets the screenshot of the current element as binary data.
Returns: Binary data of the PNG image
{ .api }
def screenshot(self, filename: str) -> boolDescription: Saves a screenshot of the current element to a PNG image file.
Parameters:
filename: The full path to save the screenshotReturns: True if the screenshot was saved successfully, False otherwise
Example:
element = driver.find_element(By.ID, 'chart')
# Save screenshot to file
element.screenshot('/path/to/element_screenshot.png')
# Get as binary data
png_data = element.screenshot_as_png()
# Get as base64 string
base64_data = element.screenshot_as_base64(){ .api }
def aria_role(self) -> strDescription: Gets the ARIA role of the current element.
Returns: The ARIA role attribute value
{ .api }
def accessible_name(self) -> strDescription: Gets the accessible name of the current element.
Returns: The accessible name of the element
Example:
button = driver.find_element(By.ID, 'submit-btn')
role = button.aria_role
name = button.accessible_name
print(f"Button role: {role}, accessible name: {name}")WebElements also support finding child elements:
{ .api }
def find_element(self, by: str = By.ID, value: Optional[str] = None) -> WebElement{ .api }
def find_elements(self, by: str = By.ID, value: Optional[str] = None) -> List[WebElement]Example:
# Find a container element
container = driver.find_element(By.ID, 'products')
# Find child elements within the container
products = container.find_elements(By.CLASS_NAME, 'product-item')
for product in products:
title = product.find_element(By.CLASS_NAME, 'product-title')
price = product.find_element(By.CLASS_NAME, 'product-price')
print(f"{title.text}: {price.text}"){ .api }
def shadow_root(self) -> ShadowRootDescription: Returns a shadow root of the element if there is one, or an error.
Returns: ShadowRoot object
Example:
# Find element with shadow DOM
host_element = driver.find_element(By.ID, 'shadow-host')
# Access shadow root
shadow_root = host_element.shadow_root
# Find elements within shadow DOM
shadow_element = shadow_root.find_element(By.CSS_SELECTOR, '.shadow-content')from selenium.common.exceptions import NoSuchElementException, TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def find_element_safely(driver, by, value, timeout=10):
"""Safely find element with timeout"""
try:
element = WebDriverWait(driver, timeout).until(
EC.presence_of_element_located((by, value))
)
return element
except TimeoutException:
print(f"Element not found: {by}={value}")
return None
# Usage
element = find_element_safely(driver, By.ID, 'submit-btn')
if element:
element.click()from selenium.webdriver.support import expected_conditions as EC
# Wait for element to be clickable
wait = WebDriverWait(driver, 10)
button = wait.until(EC.element_to_be_clickable((By.ID, 'submit-btn')))
button.click()
# Wait for element to be visible
element = wait.until(EC.visibility_of_element_located((By.ID, 'result')))
print(element.text)def wait_for_text_change(element, old_text, timeout=10):
"""Wait for element text to change"""
wait = WebDriverWait(driver, timeout)
wait.until(lambda d: element.text != old_text)
# Usage
status_element = driver.find_element(By.ID, 'status')
old_status = status_element.text
# Trigger some action
submit_button.click()
# Wait for status to update
wait_for_text_change(status_element, old_status)def interact_with_form(driver):
"""Efficient form interaction pattern"""
# Find form container once
form = driver.find_element(By.ID, 'user-form')
# Find all inputs within the form
username = form.find_element(By.NAME, 'username')
password = form.find_element(By.NAME, 'password')
submit_btn = form.find_element(By.TYPE, 'submit')
# Perform interactions
username.clear()
username.send_keys('testuser')
password.clear()
password.send_keys('password123')
# Submit form
submit_btn.click()from selenium.common.exceptions import (
NoSuchElementException,
ElementNotInteractableException,
StaleElementReferenceException
)
def safe_click(element, retries=3):
"""Safely click element with retry logic"""
for attempt in range(retries):
try:
element.click()
return True
except StaleElementReferenceException:
# Re-find the element
element = driver.find_element(By.ID, element.id)
except ElementNotInteractableException:
# Wait a bit and try again
time.sleep(0.5)
return FalseInstall with Tessl CLI
npx tessl i tessl/pypi-selenium