Source code:
<input type="button" value="+" id="hour_add" class="ui-button ui-widget ui-state-default ui-corner-all" role="button" aria-disabled="false">
My code:
driver.find_element_by_xpath("//input[contains(#id, 'hour_add')]").click();
This button is not clicked.
There could be multiple reasons for the problem and there is certainly not enough information to answer, but here are the possible reasons:
there are multiple elements matching the XPath expression and a wrong element is clicked
you might need to move to the element and click:
from selenium.webdriver.common.action_chains import ActionChains
ActionChains(driver).move_to_element(element).click(element).perform()
you might need to scroll into view of the element:
driver.execute_script("arguments[0].scrollIntoView();", element)
you might need to click via javascript:
driver.execute_script("arguments[0].click();", element)
you might need to wait for element to be clickable:
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.ID, "hour_add"))
)
element.click()
sometimes even maximizing the browser window can help:
driver.maximize_window()
When you have Id available for the element you want to click on, then just use find_element_by_id.
driver.find_element_by_id('hour_add').click()
Related
How would I get selenium python to recognise this button in HTML?
I've tried this and other tags to get it
driver.find_element_by_class_name('cookie-monster').clickbutton
print('button was clicked')
This is the button snippet code
<button class="cookie-monster__cta cookie-monster__cta--primary js-cookie-monster-accept">
<span class="glyphicon glyphicon-ok"></span>
Accept All Cookies
</button>
Your locator is wrong. The class is named cookie-monster__cta, not .cookie-monster. js-cookie-monster-accept seems to be unique class name. Use it for finding your element.
Also, you should wait for elements before clicking them.
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 20)
wait.until(EC.element_to_be_clickable(
(By.CSS_SELECTOR, "js-cookie-monster-accept")))
button = driver.find_element_by_css_selector("js-cookie-monster-accept")
button.click()
If this locator is not unique, add classes one by one to both wait and find_element_by_css_selector, like this:
.js-cookie-monster-accept.cookie-monster__cta
I want to go to this site:
http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia
Then click on the "Tabella" tab
Then see the second page (out of 64) of the table
However I failed in the first part, I cannot make a code to click on "Tabella" tab
import requests
from selenium import webdriver
driver.get('http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia')
element = driver.find_element_by_id("Tabella")
element.click()
And here is the html code that I used to search:
<li id="Tabella" class="Table_img ui-state-default ui-corner-top ui-tabs-selected ui-state-active">
<span id="span_table_img" class="span_img"></span>
Tabella </li>
Thank all!
Add time sleep before accessing the table element.
time.sleep(5)
driver.find_element_by_id('Tabella').click()
To click on Tabella tab you need to induce WebDriverWait() and wait for element_to_be_clickable() and you can use following locator.
Link Text:
driver.get("http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia")
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.LINK_TEXT,"Tabella"))).click()
XPATH:
driver.get("http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia")
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//a[text()='Tabella']"))).click()
You need to import below libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Problem with your code
You are trying to click an element before it is available/ready to click in DOM.
Solution
You need to wait for the element to load and become clickable to perform any kind of action on the same element.
Code
driver = webdriver.Chrome()
driver.get('http://www.datiopen.it/it/opendata/Mappa_delle_stazioni_ferroviarie_in_Italia')
def wait_for_element_to_be_clickable(element):
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, element)))
wait_for_element_to_be_clickable("Tabella")
element = driver.find_element_by_id("Tabella")
element.click()
print("executed")
def wait_for_element_to_be_clickable(element): this method will wait for any element to become clickable before proceeding. (you can increase the time based on your page loading time).
<td role="presentation" valign="top" class=" x-trigger-cell x-unselectable" style="width:28px;" id="ext-gen1147">
<div class="x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-first rp-icon-expanded" role="presentation" id="ext-gen1146">
</div></td>
im trying to click this div elementbut throwing exception.My code is:
driver.find_element_by_xpath("//div[#id='ext-gen1146']").click()
driver.find_element_by_xpath("//*[#id='ext-gen1147']").click()
driver.find_element_by_xpath("//div[#class='x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-first rp-icon-expanded' and #id='ext-gen1146']")
selenium.common.exceptions.NoSuchElementException: Message: no such
element: Unable to locate element:
{"method":"xpath","selector":"//*[#id='ext-gen1147']"} (Session
info: chrome=80.0.3987.163)
Try below solution and check your element is not dynamic and its not inside the iframe, if its in iframe then you have to switch to it and then click on your eelement.
wait.until(EC.element_to_be_clickable((By.ID, "ext-gen1147"))).click()
or
wait.until(EC.element_to_be_clickable((By.XPATH, "x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-first rp-icon-expanded"))).click()
Note : please add below imports to your solution
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
To switch to iframe you can use below code, Make sure you have only one iframe or else you can use ID/Name of iframe to identify correct element before switching:
iframe = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.TAG_NAME, 'iframe')))
driver.switch_to.frame(iframe)
I think maybe you need to wait for visibility first, maybe this helps you https://stackoverflow.com/a/19537085/2069610... for example:
WebDriverWait wait = new WebDriverWait(driver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<"ext-gen1146>));
To click on dynamic element Induce WebDriverWait() and element_to_be_clickable() and following css selector.
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div.rp-icon-expanded[id^='ext-gen'][role='presentation']"))).click()
You need to import following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
you can try Actions class to click on the expected element -
Actions actions = new Actions(driver);
actions.click(element).build().perform();
if this also not works try using JavascriptExecutor
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor..executeScript("arguments[0].click();", element);
I am working with Python and Selenium but I got stuck scraping a page trying to scroll down until selenium finds the classic "Show more" button (that seems to be hidden).
What I have done 'til now is the following:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
element = browser.find_element_by_xpath('//*[#id="ember371"]/button') # you can use ANY way to locate element
coordinates = element.location_once_scrolled_into_view # returns dict of X, Y coordinates
browser.execute_script('window.scrollTo({}, {});'.format(coordinates['x'], coordinates['y']))
However, whatever I try to do Python throws me several kind of errors, for example the below.
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="ember371"]/button"}
(Session info: chrome=80.0.3987.122)
Could it be due to the fact that the button is hidden?
Below is the HTML code for the button I am looking for and that I would like to click on.
<button class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid" aria-controls="skill-categories-expanded" aria-expanded="false" data-control-name="skill_details" data-ember-action="" data-ember-action-2182="2182">
<span aria-hidden="true">
Show more
</span>
<span class="visually-hidden">
BLA BLA BLA
</span>
<li-icon aria-hidden="true" type="chevron-down-icon" class="pv-skills-section__chevron-icon" size="small"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" data-supported-dps="16x16" fill="currentColor" width="16" height="16" focusable="false">
<path d="M8 9l5.93-4L15 6.54l-6.15 4.2a1.5 1.5 0 01-1.69 0L1 6.54 2.07 5z"></path>
</svg></li-icon>
</button>
#################################################################################
It worked with the following:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
# scroll down smoothly
scheight = .1
while scheight < 1.0:
browser.execute_script("window.scrollTo(0, document.body.scrollHeight*%s);" % scheight)
scheight += .1
time.sleep(1)
try:
browser.execute_script("arguments[0].scrollIntoView(true);", WebDriverWait(browser, 10).until(EC.visibility_of_element_located((By.XPATH, "//button[#aria-controls='skill-categories-expanded' and #data-control-name='skill_details']/span[normalize-space()='Show more']"))))
browser.execute_script("arguments[0].click();", WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#aria-controls='skill-categories-expanded' and #data-control-name='skill_details']/span[normalize-space()='Show more']"))))
except:
print('NO')
The element Show more within linkedin website is EmberJS enabled element. So to scrollIntoView 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:
driver.execute_script("arguments[0].scrollIntoView(true);", WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "button[aria-controls='skill-categories-expanded'][data-control-name='skill_details']>span"))))
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-controls='skill-categories-expanded'][data-control-name='skill_details']>span"))))
Using XPATH:
driver.execute_script("arguments[0].scrollIntoView(true);", WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, "//button[#aria-controls='skill-categories-expanded' and #data-control-name='skill_details']/span[normalize-space()='Show more']"))))
driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#aria-controls='skill-categories-expanded' and #data-control-name='skill_details']/span[normalize-space()='Show more']"))))
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
You can try using a while loop here, check for the existence of the button as the condition, and put the browser.execute_script in the body. In this way, you would start by checking if the button exists, if not then scroll for 200 px or so (just make sure you don't scroll past the button) until the button appears.
You can first try to find if the "show more" button is enabled by using the isEnabled() method. This method returns “true” value if the specified web element is enabled on the web page otherwise returns “false” value if the web element is disabled on the web page.
If isEnabled() method returns False, you can then try scrolling down the page till the element is visible and use the isEnabled() method again.
Also, try replacing id with XPath. It may work.
I am learning Selenium and trying to click the GO button:
https://speedtest.telstra.com/
<button class="button background-primary-hover text-primary" aria-label="start your speedtest">
<span style="font-size: unset; overflow-wrap: unset;">GO</span></button>
What are all possible Selenium methods to get that button clicked,
elem = driver.find_element_by_....???
I also would like to see what I found, so should print(elem.text) then be used?
As per the website https://speedtest.telstra.com/ the desired element is within an <iframe> so you need to induce WebDriverWait to switch to the <iframe> and then look out for the element and you can use the following solution:
Using XPATH:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='speed-test' and #src='//telstra-nbn.speedtestcustom.com']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='button background-primary-hover text-primary']/span[contains(.,'GO')]"))).click()
Using CSS_SELECTOR:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"//iframe.speed-test[src*='speedtestcustom']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.button.background-primary-hover.text-primary[aria-label='start your speedtest']>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
You have to use xpath, there is xpath helper tool for chrome. You can install it.
button = driver.find_element_by_xpath("your xpath")
button.click()
Try this:
browser.find_element_by_class_name("button background-primary-hover text-primary").click()
Since it will select the element and click it.