How to click on button with selenium in Python - python

my HTML-Code is following:
<button aria-label="Nur zuhören" aria-disabled="false" class=
"jumbo--Z12Rgj4 buttonWrapper--x8uow audioBtn--1H6rCK">
and I want to click on the button with following Python-Code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as wait
wait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "jumbo--Z12Rgj4 buttonWrapper--x8uow audioBtn--1H6rCK"))).click
but it's not working

If you want to find a element with multiple class name, you can use XPATH.
I simplify you html as <button class="aaa bbb ccc">
Then you can use (By.XPATH, "//button[contains(#class, 'aaa') and contains(#class, 'bbb') and contains(#class, 'ccc')]") to find this button.

Try to capture the element in webelement and then try to execute the expected condition command. It should work
click_ele=driver.find_element_by_class_name(jumbo--Z12Rgj4 buttonWrapper--x8uow audioBtn--1H6rCK)
wait(driver, 20).until(EC.element_to_be_clickable(click_ele.click)))
wait(driver, 20).until(EC.element_to_be_clickable((By.CLASS_NAME, "jumbo--Z12Rgj4 buttonWrapper--x8uow audioBtn--1H6rCK"))).click
.click might not be coming as an option in the dropdown, as it take 2 positional arguments

Selenium can't find multiple class names by class name instead use css selector.
Try below css selector.
wait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, ".jumbo--Z12Rgj4.buttonWrapper--x8uow.audioBtn--1H6rCK"))).click()
OR
wait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[aria-label='Nur zuhören']"))).click()
Hope this helps.

Related

Selenium can't find the div element to click

I'm using selenium to automate some tasks with webdriver.
Turns out I can't find a div to click on, selenium just can't find it.
Does anyone have a suggestion?
HTML :
<div aria-controls="leftAdvPnl_body" aria-expanded="false" aria-haspopup="true" class="rich-stglpanel-header " id="leftAdvPnl_header" onclick="SimpleTogglePanelManager.toggleOnClient(event,'leftAdvPnl');" onkeypress="return keypressclickhandle(event);" role="link" tabindex="0"><div aria-hidden="true" class="rich-stglpanel-marker"><div class="rich-stglpnl-marker" aria-hidden="true" id="leftAdvPnl_switch_on" style="display: none">«</div><div class="rich-stglpnl-marker" aria-hidden="true" id="leftAdvPnl_switch_off">»</div></div><span id="leftAdvPnl_header_label">Pesquisar</span><span aria-hidden="true"> </span></div>
Code phyton:
while len(navegador.find_elements_by_xpath('//*[#id="leftAdvPnl_header"]')) < 1:
time.sleep(1)
print("Procurando formulário do processo")
link=navegador.find_element_by_xpath("//*[#id="leftAdvPnl_header"]")
link.click()
Thanks!
You have 2 nested double quotes, instead of "//*[#id="leftAdvPnl_header"]" use '//*[#id="leftAdvPnl_header"]'
You need to wait for an element to be clickable, so try:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="leftAdvPnl_header"]'))).click()
To click on the element with text as Pesquisar you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element(By.CSS_SELECTOR, "div.rich-stglpanel-header#leftAdvPnl_header span#leftAdvPnl_header_label").click()
Using xpath:
driver.find_element(By.XPATH, "//span[text()='Pesquisar' and #id='leftAdvPnl_header_label']").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, "div.rich-stglpanel-header#leftAdvPnl_header span#leftAdvPnl_header_label"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Pesquisar' and #id='leftAdvPnl_header_label']"))).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
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
xpath that you should check :
//div[#id='leftAdvPnl_header']
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
If we have 1/1 matching node, Please make sure that :
This div is not under an iframe.
This div is not under a shadow-root.
You should not be on new tab/windows launched by selenium.
Code :
try:
WebDriverWait(navegador, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#id='leftAdvPnl_header']"))).click()
print("Clicked on web element")
except:
pass
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Updated :
CSS are far more better locator than XPath, please try the below one :
div[onclick^='SimpleTogglePanelManager.toggleOnClient'][onclick*='(event,'][onclick*='leftAdvPnl']
Same way to check if we have 1/1 matching node or not.
To click, there are 4 ways in Selenium.
Code trial 1:
time.sleep(5)
driver.find_element_by_css_selector("div[onclick^='SimpleTogglePanelManager.toggleOnClient'][onclick*='(event,'][onclick*='leftAdvPnl']").click()
Code trial 2:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div[onclick^='SimpleTogglePanelManager.toggleOnClient'][onclick*='(event,'][onclick*='leftAdvPnl']"))).click()
Code trial 3:
time.sleep(5)
button = driver.find_element_by_css_selector("div[onclick^='SimpleTogglePanelManager.toggleOnClient'][onclick*='(event,'][onclick*='leftAdvPnl']")
driver.execute_script("arguments[0].click();", button)
Code trial 4 :
time.sleep(5)
button = driver.find_element_by_css_selector("div[onclick^='SimpleTogglePanelManager.toggleOnClient'][onclick*='(event,'][onclick*='leftAdvPnl']")
ActionChains(driver).move_to_element(button).click().perform()
Imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains

Python Selenium Chrome Webdriver : bound method WebElement.click

I'm new to python. I tried to extract data on https://live-cosmos.finq.com/trading-platform/?path=details&symbol=SILVER#login by giving user name and password. It works.
But when try to hit on another button it doesn't work. ('Deposite' or the 'X' to close)
HTML of the Deposit element:
<button class="btn btn-primary">Deposit</button>
Snapshot of the Deposit element:
My code is
from selenium import webdriver
import time
driver = webdriver.Chrome(executable_path="C:\\Chromedriver\\Chromedriver.exe")
driver.maximize_window();
driver.get('https://live-cosmos.finq.com/trading-platform/?path=details&symbol=SILVER#login')
time.sleep(5)
driver.find_element_by_xpath("/html/body/div[2]/div[4]/div[2]/div/div/div/div/div/div/form/div/div[3]/div[1]/input").send_keys("username#gmail.com")
driver.find_element_by_xpath("/html/body/div[2]/div[4]/div[2]/div/div/div/div/div/div/form/div/div[3]/div[2]/input").send_keys("password_here")
driver.find_element_by_xpath("/html/body/div[2]/div[4]/div[2]/div/div/div/div/div/div/form/div/div[3]/button").click()
time.sleep(20) # wait for loading
driver.find_element_by_xpath("/html/body/div[8]/div/div/div/div/div[3]/div[1]/div[4]/button").click()
output is
<bound method WebElement.click of <selenium.webdriver.remote.webelement.WebElement (session="28205c2be15699403ddfcc3f3ce2fa33", element="03ae577c-b3d4-423c-b7ed-1d9c5ea3ea1a")>>
Can you please help me to solve this (or a different approach) and go forward to scrape some text from the website.
Thank you in advance.
The click on the element with text as Deposit you have to induce WebDriverWait 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.btn.btn-primary"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-primary' and text()='Deposit']"))).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

Find element by only a part of its XPath using Selenium

I'm trying to find elements which have changing XPaths with only one part staying the same:
//*[#id="foo"]div[2]/div[1]/time
//*[#id="bar"]div/div[2]/div[1]/time
//*[#id="bat"]div[1]div[2]/div[1]/time
I already tried using driver.find_element_by_xpath("//*[contains(text(), '/div[2]/div[1]/time')]") but this doesn't seem to work.
Here is some example HTML:
<div class="entry-container">
<div class="entry-head">
<h3> some text </h3>
<time class="timestamp" datetime="2020-01-23 08:04:32 UTC">
Today at 18:34
</time>
</div>
</div>
I want to get the text from the time element.
The following XPath expression:
//div/div//time
will give you all time elements anywhere having two div elements as ancestor. This works for the example paths you provided.
Try this x path locator:
.//div[#class]/time
To handle dynamic element induce WebDriverWait() and visibility_of_element_located() and following xpath options.
XPath1 :
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,"//h3[contains(.,'some text')]/following-sibling::time[1]"))).text)
XPath2 :
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,"//h3[contains(.,'some text')]/following::time[1]"))).text)
XPath3 :
print(WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.XPATH,"//div[#class='entry-head']//h3[contains(.,'some text')]/following-sibling::time[1]"))).text)
You need to add following libraries.
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
try with below code using Xpath and CSS with webdriver wait so element will be loaded in DOM
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Xpath -1
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "(//time[#class='timestamp'])[1]")))
OR
Xpath -2
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.XPATH, "(//time)[1]")))
By CSS
element = WebDriverWait(driver, 20).until(
EC.element_to_be_clickable((By.CSS_SELECTOR , "time.timestamp")))

How do I make Selenium Python click on a button element?

So I just started using Selenium for Python and I am trying to click on a button element that is buried into a few div elements; I've tried so many things but nothing works. Everything in the code works besides the last part which is waiting for the button to be clickable and then clicking it. I would greatly appreciate some help here, thanks. :)
HTML:
Code trials:
Error stacktrace:
To click on **Maybe Later** button.
Induce WebDriverWait() and element_to_be_clickable() and following XPATH or CSS Selector.
XPATH:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//div[#class='modal-footer']//button[#Class='btn btn-danger x' and text()='Maybe Later']"))).click()
CSS Selector:
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"div.modal-footer button.btn.btn-danger.x[style='danger']"))).click()
You need to import following libraries.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
css selectors will become your best friend,
you should always look to add as many attributes as possible
maybe_later_css = 'button[class="btn btn-danger"]'
# type str, '<tag-name>[<attribute-name> = <attribute-value>]'
driver.find_element_by_css_selector(maybe_later_css).click()
follow this format for all elements, its superior and works as expected every time
the only complication is when there exists multiple buttons with them same class name, in which case you should find a different attribute to fill the [] brackets
The element with text as Maybe Later is within a Modal Dialog Box so to locate and 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:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.modal-footer#eFooter button.btn.btn-danger.x[style='danger']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='modal-footer' and #id='eFooter']//button[#class='btn btn-danger x' and #style='danger']"))).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 using python: how to correctly click() an element?

while learning how to use selenium, Im trying to click an element but nothing happens and Im unable to reach the next page. this is the relevant page: http://buyme.co.il and Im trying to click: הרשמה
I managed to print the desired element (הרשמה) so I guess Im reaching the correct place in the page. but 'click()' doesnt work.
the second span <span>הרשמה</span> is what i want to click:
<li data-ember-action="636">
<a>
<span class="seperator-link">כניסה</span>
<span>הרשמה</span>
</a>
</li>
for elem in driver.find_elements_by_xpath('//* [#id="ember591"]/div/ul[1]/li[3]/a/span[2]'):
print (elem.text)
elem.click()
also tried this:
driver.find_element_by_xpath('//*[#id="ember591"]/div/ul[1]/li[3]/a').click()
I expected to get to the "lightbox" which contain the registration fields.
Any thoughts on the best way to accomplish this?
Explicit Waits - An explicit wait is a code you define to wait for a certain condition to occur before proceeding further in the code.
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
browser = webdriver.Chrome()
browser.get("https://buyme.co.il/")
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.ID, 'ember591')))
elm = browser.find_elements_by_xpath('//div[#id="ember591"]/div/ul[1]/li[3]/a')
elm[0].click()
Update:
WebDriverWait(browser, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, 'login')))
email = browser.find_elements_by_xpath("//form[#id='ember1005']/div[1]/label/input")
email[0].send_keys("abc#gmail.com")
password = browser.find_elements_by_xpath("//form[#id='ember1005']/div[2]/label/input")
password[0].send_keys("test1234567")
login = browser.find_elements_by_xpath('//form[#id="ember1005"]/button')
login[0].click()
The desired element is an Ember.js enabled element so to locate the element you have to induce WebDriverWait for the element to be clickable and you can use the following Locator Strategy:
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='הרשמה']"))).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

Categories