Find an element with xpath misses a required positional element - selenium

I want to click on a radio-button in my html-file.
The following code:
from selenium.webdriver.remote import webdriver
element = webdriver.WebDriver.find_element_by_xpath("//input[#type='radio' and #name='AlarmMode']")
element.click()
gives me the error:
TypeError: find_element_by_xpath() missing 1 required positional argument: 'xpath'
Which argument is missing?

You need to first instantiate a webdriver object and then call find_element_by_xpath() on it:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get(url)
element = driver.find_element_by_xpath("//input[#type='radio' and #name='AlarmMode']")
element.click()

Related

Selenium: 'function' object has no attribute 'click'

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.
Your code is incorrect. You can find below an example of how you can use Expected Conditions (along with WebdriverWait):
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
## [...define your driver here, other imports etc]
wait = WebDriverWait(driver, 25)
##[open a url, etc]
element = wait.until(EC.presence_of_element_located((By.XPATH, '//div[#class="input-group"]')))
element.click()
Selenium documentation can be found here.
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 usecase
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.
Solution
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

Selenium find element error, but same code with js can work

use the python execute can find the element bottom and click, it works:
driver.execute_script("document.getElementsByClassName(\"g-c-R webstore-test-button-label\")[0].click()")
but with the similar code, the python code can not work:
element_install_bottom=driver.find_element(by=By.ID, value=r'g-c-R webstore-test-button-label')
and throw the exception:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="g-c-R webstore-test-button-label"]"}
and have try by.ID, by.ClassName; but always throw the exception.
the whole code as below:
from selenium import webdriver
from selenium.webdriver.common.by import By
import selenium.webdriver.support.ui as ui
import time
option = webdriver.ChromeOptions()
USER_DATA_PATH = r"D:\Chrome\User Data 3"
option.add_argument(f'--user-data-dir={USER_DATA_PATH}')
option.add_experimental_option('excludeSwitches', ['enable-automation'])
print(option.arguments)
driver = webdriver.Chrome(options=option)
extension_url = "https://chrome.google.com/webstore/detail/dark-reader/eimadpbcbfnmbkopoojfekhnkhdbieeh?hl=zh-CN"
driver.get(extension_url)
time.sleep(60)
element_install_bottom=driver.find_element(by=By.ID, value=r'g-c-R webstore-test-button-label')
print(element_install_bottom)
You're seeing that exception as there is no element with that ID, that value is it's class.
Python:
driver.find_element_by_class_name("g-c-R webstore-test-button-label")
or:
driver.find_element(By.CLASS_NAME, "g-c-R webstore-test-button-label")

Selenium can't find by element

I try to scroll down by element class. I need to scroll by tweet in twitter.com
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver = webdriver.Firefox()
driver.get('http://twitter.com/elonmusk')
sleep(5)
while True:
html = driver.find_element_by_class_name('css-901oao r-1fmj7o5 r-1qd0xha r-a023e6 r-16dba41 r-rjixqe r-bcqeeo r-bnwqim r-qvutc0')
html.send_keys(Keys.END)
I have error:
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .css-901oao r-1fmj7o5 r-1qd0xha r-a023e6 r-16dba41 r-rjixqe r-bcqeeo r-bnwqim r-qvutc0
That class name have spaces in your code, class_name does not work with spaces, try the below xpath :
//div[#data-testid='tweet']
and you can write like this in code :
counter = 1
while True:
html = driver.find_element_by_xpath(f"(//div[#data-testid='tweet'])[{counter}]")
counter = counter + 1
html.send_keys(Keys.END)

'NoneType' object is not callable error while attempting to click on an element returned with BeautifulSoup using Selenium

I want to click on element targeted with beautifulsoup using click() method in selenium but this error is showing:
'NoneType' object is not callable
Example of my code:
from selenium import webdriver
from bs4 import BeautifulSoup
tabs = deals_tabs.find_all('div',{'class':'FilterSort__filter___36MvO'})
tabs.pop(0)
for tab in tabs:
category = tab.text
tab.click()
findall()
findall() finds all the matches and returns them as a list of strings, with each string representing one match.
So tabs is a list of strings as well as tab.
But click() is a WebElement method and can't be called on a string. Hence you see the error.

Selenium, groovy, can't perform any click(), sendKeys() or similar functions

I am not sure what I'm missing from my code. But I am trying to run a basic Groovy script, where I'm finding an element from the page, and clicking on it.
My code works, to the point where I add .click() or .sendKeys().
A few things to note are I'm running selenium on ReadyAPI. I have followed all the instructions from their help page to make sure I have the right drivers in the right folders.
My code is as follows:
import java.util.ArrayList;
import org.openqa.selenium.*
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.WebElement
import org.openqa.selenium.chrome.ChromeDriver
def PATH_TO_CHROMEDRIVER = context.expand( '${PATH_TO_CHROMEDRIVER}' );
System.setProperty("webdriver.chrome.driver", PATH_TO_CHROMEDRIVER);
def WebDriver driver = new ChromeDriver();
driver.get("https://www.rakuten.com/");
WebElement loginButtonId = driver.findElementsByXPath("//*[#name='email_address']");
loginButtonId.click();
driver.close();
return
The error msg I get is the following:
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '[]' with class 'java.util.ArrayList' to class 'org.openqa.selenium.WebElement' due to: groovy.lang.GroovyRuntimeException: Could not find matching constructor for: org.openqa.selenium.WebElement() error at line: 12
I appreciate it if anyone could help here.
Thanks,
Your mistake is in this line:
WebElement loginButtonId = driver.findElementsByXPath("//*[#name='email_address']");
findElements you should use when you need to detect a list of elements,
If you want to get a single element use findElement:
WebElement loginButtonId = driver.findElementByXPath("//*[#name='email_address']");