I am running into this issue when trying to click a button using selenium. The button html reads as below:
<button class="Component-button-0-2-65 Component-button-d1-0-2-68">and 5 more</button>
My code is here:
button = EC.element_to_be_clickable((By.XPATH,'.//button[contains(@class,"Component-button-d")]'))
if button:
print("TRUE")
button.click()
My output is:
TRUE
Traceback (most recent call last):
File "", line 47, in <module>
button.click()
AttributeError: 'function' object has no attribute 'click'
I am stumped as to why 'button' element is found by selenium (print(True)
statement is executed) but then the click()
method returns an attribute error.
This is the page I am scraping data from: https://religiondatabase.org/browse/regions I am able to extract all the information I need on the page, so the code leading up to the click is working.
I was expecting the item to be clickable. I'm not sure how to troubleshoot the attribute error (function object has no attribute click). Because it I paste the xpath into the webpage, it highlights the correct element.
The element search is always done through the driver
object which is the WebDriver instance in it's core form:
driver.find_element(By.XPATH, "element_xpath")
But when you apply WebDriverWait, the wait
configurations are applied on the driver
object.
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "element_xpath")))
So even during WebDriverWait the driver
object needs to be present along with the expected_conditions and the locator strategy.
This line of code:
button = EC.element_to_be_clickable((By.XPATH,'.//button[contains(@class,"Component-button-d")]'))
button object references to a junk value but on probing returns true
and prints TRUE but the click can't be performed as button
is not of WebElement type.
Given the HTML:
<button class="Component-button-0-2-65 Component-button-d1-0-2-68">and 5 more</button>
To click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using XPATH with classname:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "//button[contains(@class,'Component-button-d')]"))).click()
Using XPATH with classname and innerText:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(@class,'Component-button-d') and text()='and 5 more']"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC