Last Updated on July 14, 2022 by Jay
If you are trying to fix the Selenium AttributeError: ‘WebDriver’ object has no attribute ‘find_element_by_xpath’, then you are at the right place!
What Caused the Error
I recently upgraded selenium to version 4.3.0., then started to have this problem “WebDriver” object has no attribute “find_element_by_xpath”. This is because starting from version 4.3.0., selenium has changed the usual API driver.find_element_by_xxx. Instead, the new method syntax is now simply driver.find_element(by_what, element). For example:
driver.find_element('xpath', '//*[@id="main"]/footer/div[1]/div/span[2]')
## OR
from selenium.webdriver.common.by import By
driver.find_element(By.Name, 'name')
Fixing AttributeError “find_element_by_xpath”
Now we know the root cause of the error message, and fixing it is easy. We’ll look at two approaches.
Fix # 1 – Install An Older Selenium Version
The old API still works in earlier versions 4.2.0 and prior. If we try to run the old API in those earlier versions, we’ll get a warning message, but the program still runs okay. This is telling us that the old approach find_element_by_xxx is going away, better start using the new one!
Warning (from warnings module):
File "<pyshell#8>", line 1
DeprecationWarning: find_element_by_xpath is deprecated. Please use find_element(by=By.XPATH, value=xpath) instead
If you are okay with using an older version of selenium, you can downgrade the library using pip with an argument –force-reinstall, as well as specifying which version we want to use. The below will overwrite our current selenium, then install version 4.2.0 instead.
pip install selenium==4.2.0 --force-reinstall
We need to consider the following pros and cons of downgrading a library:
Pros
- Easier to get code to work again
- No coding changes required
Cons
- Have to re-write our code
- May not get the latest support or the latest features the library has to offer
Fix # 2 – Update Our Code (And Use the Latest Version of Selenium)
If the decision is to upgrade to the latest selenium, then we’ll have to update the code, which might not be that bad. Doing find+replace a few times should update all the code for us.
Below is a comparison between the old and new APIs for finding web elements, as we can see the new API is now just find_element(), then we specify what element we want to find as the first argument.
Old API | New API |
find_element_by_id(‘id’) | find_element(By.ID, ‘id’) |
find_element_by_name(‘name’) | find_element(By.NAME, ‘name’) |
find_element_by_xpath(‘xpath’) | find_element(By.XPATH, ‘xpath’) |
find_element_by_link_text(‘link_text’) | find_element(By.LINK_TEXT, ‘link_text’) |
find_element_by_partial_link_text(‘partial_link_text’) | find_element(By.PARTIAL_LINK_TEXT, ‘partial_link_text’) |
find_element_by_tag_name(‘tag_name’) | find_element(By.TAG_NAME, ‘tag_name’) |
find_element_by_class_name(‘class_name’) | find_element(By.CLASS_NAME, ‘class_name’) |
find_element_by_css_selector(‘css_selector’) | find_element(By.CSS_SELECTOR, ‘css_selector’) |
Below are some pros and cons if we choose to upgrade to the latest version of Selenium:
Pros
- Latest features, and full support
- Future-proof
Cons
- Need to re-write code, which can be a lot of work for large projects
Man, you saved my ass!
Thanks.