AttributeError: WebDriver object has no attribute find_element_by_name in Selenium
Replace driver.find_element_by_name('query') with driver.find_element(By.NAME, 'query') by importing from selenium.webdriver.common.by import By.
Root Cause Analysis
This error occurs when Python tries to invoke deprecated locator methods such as find_element_by_name() or find_element_by_id() on a Selenium WebDriver instance, but Selenium 4.3+ has completely removed these individual locator methods in favor of the unified find_element(By.*, ...) API.
The Selenium 4 API Modernization
In Selenium 3, the WebDriver class provided dozens of separate locator methods:
find_element_by_id(id)find_element_by_name(name)find_element_by_xpath(xpath)find_element_by_css_selector(css)find_element_by_class_name(class_name)
In Selenium 4.0, these methods were marked deprecated, and starting in Selenium 4.3.0, they were permanently removed from the WebDriver class to streamline the API across language bindings (Python, Java, C#, JavaScript). Calling any find_element_by_* method under modern Selenium versions raises AttributeError.
Why This Error is Widespread
Many online web scraping tutorials, StackOverflow answers, and legacy automation codebases were written for Selenium 3. Developers copying these snippets into modern Python environments immediately encounter this AttributeError.
Reproduction Code (MCVE)
# In Selenium 4.3+, find_element_by_name was removed from WebDriver
class LegacyWebDriver:
pass
driver = LegacyWebDriver()
driver.find_element_by_name('search_query')
Solution 1: Use `driver.find_element(By.NAME, ...)` with the `By` Class
Import By from selenium.webdriver.common.by and pass the locator strategy as the first argument to find_element().
from selenium.webdriver.common.by import By
# Demonstration of the unified locator strategy mapping
locator_strategies = {
'name': (By.NAME, 'q'),
'id': (By.ID, 'search-input'),
'xpath': (By.XPATH, '//button[@type="submit"]'),
'css': (By.CSS_SELECTOR, 'div.results > a')
}
for strategy, (by_type, query) in locator_strategies.items():
print(f'Migrated strategy for {strategy}: By.{by_type} with locator "{query}"')
Solution 2: Multiple Elements Locator with `find_elements(By.CSS_SELECTOR, ...)`
Replace find_elements_by_* with driver.find_elements(By.*, ...) which returns a list of matching WebElements.
from selenium.webdriver.common.by import By
# Migration table for multiple elements:
# Old: driver.find_elements_by_class_name('product')
# New: driver.find_elements(By.CLASS_NAME, 'product')
css_locator = (By.CSS_SELECTOR, 'input[name="search_query"]')
print(f'Ready to find elements using: {css_locator}')
Full Migration Cheat Sheet
| Deprecated Selenium 3 Method | Modern Selenium 4+ Replacement |
|---|---|
find_element_by_id('val') |
find_element(By.ID, 'val') |
find_element_by_name('val') |
find_element(By.NAME, 'val') |
find_element_by_xpath('val') |
find_element(By.XPATH, 'val') |
find_element_by_css_selector('val') |
find_element(By.CSS_SELECTOR, 'val') |
find_element_by_class_name('val') |
find_element(By.CLASS_NAME, 'val') |
find_element_by_link_text('val') |
find_element(By.LINK_TEXT, 'val') |
Contrasting AttributeError with NoSuchElementException: AttributeError occurs at method dispatch time because the method does not exist on WebDriver. NoSuchElementException occurs at runtime when the method exists and executed correctly, but no HTML element on the web page matched the locator.