I am trying to pull some quotes on a website. To get the quote you have to click the Javascript button below:
Below is my python code to click the button:
driver = webdriver.Edge()
driver.get("http://generatorland.com/glgenerator.aspx?id=86")
driver.find_element(By.XPATH,"//a[#href='JavaScript:void(0);']").click()
However, when I run the code to test the button press, it throws an error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//a[#href='JavaScript:void(0);']"}
(Session info: MicrosoftEdge=110.0.1587.46)
Why can't it find the button, even when I specify the href sample for the XPATH to find?
You can move a step deeper and use the <img> tag.
Solution
The desired element is a dynamic element, so to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a > img[alt='Confucius']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a/img[#alt='Confucius']"))).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
Related
I am trying to click on a button using selenium. My code states it is unable to find the css_selector with said class name. The class name has spaces in it, which lead me to use the css_selector object. When I try to pass the class name in the 'css_selector' object, it fails since the class name is a string, which is not callable. The website is password protected otherwise I would share the full code. This is what I have so far.
# Button I wish to click
See Full List
# Once button is clicked, it changes to:
See Full List
What I have tried:
driver.find_element(By.CSS_SELECTOR("btn btn-alt see-full-list-btn")) # str object not callable
driver.find_element(By.CSS_SELECTOR,"btn btn-alt see-full-list-btn")
# Message: no such element: Unable to locate element: {"method":"css selector","selector":"btn btn-alt see-full-list-btn"}
As you've mentioned
The class name has spaces in it, which lead me to use the css_selector
this is right approach, however you should also make sure that one
One should remove the space and put a .
. represent class in CSS.
So the below code should work:
driver.find_element(By.CSS_SELECTOR, ".btn.btn-alt.see-full-list-btn")
or you can even use it with the tag a
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")
or the recommended solution would be to use with explicit waits:
see_full_list_button = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")))
see_full_list_button.click()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
There is no necessity to focus on the element HTML after the click is already invoked.
As per the HTML
See Full List
you can use either of the following locator strategies:
Using link_text:
driver.find_element(By.LINK_TEXT, "See Full List").click()
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn").click()
Using xpath:
driver.find_element(By.XPATH, "//a[#class='btn btn-alt see-full-list-btn' and text()='See Full List']").click()
Ideally to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "See Full List"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='btn btn-alt see-full-list-btn' and text()='See Full List']"))).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
I am trying to click on the following button on a linkedin page using selenium:
<button id="ember607" class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view" data-control-name="share.post"><!---->
<span class="artdeco-button__text">
Post
</span></button>
I have tried to use:
driver.find_element_by_id, but the id of the button seems to keep changing number
driver.find_element_by_xpath, but this contains the button number, so also fails
driver.find_element_by_class_name('share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view'), this fails even though the class name is correct ?
Basically, all methods generate the same error message:
Exception has occurred: NoSuchElementException
Message: no such element: Unable to locate element:{[*the_error_is_here*]}
I have also tried the xpath contains() method, but this does not find the button.
What would be the correct way to click on this button please ?
I am using python version 3.9 on windows with driver = webdriver.Chrome
The element is an Ember.js enabled element. So to click() on the element with text as Post you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text").click()
Using xpath:
driver.find_element_by_xpath("//button[contains(#class, 'share-actions__primary-action') and #data-control-name='share.post']/span[#class='artdeco-button__text' and contains(., 'Post')]").click()
Ideally, 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 CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(#class, 'share-actions__primary-action') and #data-control-name='share.post']/span[contains(., 'Post')]"))).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
References
You can find a couple of relevant detailed discussions in:
Selenium - Finding element based on ember
Automate Ember.js application using Selenium when object properties are changed at run-time
Ember: Best practices with Selenium to make integration tests in browser
Ember dropdown selenium xpath
Sometimes there are problems with buttons that are not clickable at the moment.
Try this:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 10)
button = wait.until(EC.element_to_be_clickable((By.XPATH, '[YOUR X_PATH TO THE BUTTON]')))
driver.execute_script("arguments[0].click()", button)
It's not the cleanest way to click any Button with selenium, but for me this method works mostly everytime.
//button[#class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view"].
Or
//button[contains(#id,'ember')]
Find the span with Post and click it's button tag.
//span[contains(text(), 'Post')]/parent::button
By xpath this should work:
//button/span[contains(text(), "Post")]
Combine it with a wait for the element:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button/span[contains(text(), "Post")]"))
)
The problem with your by class selectors is the multiple class names. See this question: How to get elements with multiple classes for more details on how to overcome that.
I got a BUTTON variable for those buttons:
GoMailsBTN = browser.find_element_by_class_name("D(ib) Fz(14px) Fw(b) Lh(24px) Pstart(38px)")
GoMailsBTN.click()
and there is not like any id you can go check it out by yourself if you want!
This is the error that pops out
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified
Anyone got any idea why this is?
Snapshot of the button:
The class name is dynamic and can change, in this case, you can use xpath:
browser.find_element_by_xpath("//li//a[contains(#href ,'mail') and not(#id)]")
The desired element is a JavaScript enabled element so to click on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://in.yahoo.com/?p=us')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a#header-mail-button span"))).click()
Using XPATH:
driver.get('https://in.yahoo.com/?p=us')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#id='header-mail-button']//span"))).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
Browser Snapshot:
I am trying to search a number in a web page (https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces).
I know the name of the input element is: "vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit", however when I try to find the element I got this error:
"NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"[name="vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit"]"}
(Session info: chrome=81.0.4044.138)"
This is what I have tried:
from selenium import webdriver
driver = webdriver.Chrome("C:\\Users\\jcherrerab\\Anaconda3\\Lib\\site-packages\\selenium\\webdriver\\chrome\\chromedriver.exe")
driver.get("https://muisca.dian.gov.co/WebRutMuisca/DefConsultaEstadoRUT.faces")
driver.find_element_by_name("vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit").send_keys("860003020")
Can you help me pls?
The name attribute of the <input> element contains the : character as in:
vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit
And : bears a special effect when used within a css-selectors. Hence your program fails to find the desired element and raises NoSuchElementException
Solution
To find the element you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("input[name='vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit']")
Using xpath:
driver.find_element_by_xpath("//input[#name='vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit']")
Best practices
As you are invoking send_keys() ideally you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit']"))).send_keys("860003020")
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#name='vistaConsultaEstadoRUT:formConsultaEstadoRUT:numNit']"))).send_keys("860003020")
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
Browser Snapshot:
Reference
You can find a couple of relevant discussions in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
I'm trying to find the element and click for the button "Not Now". I've tried with with css_selector, xpath, but I"m unable at all to find the proper way.
HTML:
To locate and click() on the element with text as Not Now you can use the following Locator Strategy:
Using xpath:
driver.find_element_by_xpath("//button[text()='Not Now']").click()
However, the element looks dynamic to me so you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategy:
Using XPATH:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div//button[text()='Not Now']"))).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
Reference
You can find a couple of relevant discussions in:
What does contains(., 'some text') refers to within xpath used in Selenium
While fetching all links,Ignore logout link from the loop and continue navigation in selenium java
How does dot(.) in xpath to take multiple form in identifying an element and matching a text