Selenium unable to locate and click a button - python

I have tried to make my script click the checkout button with WebDriverWait, XPath, Class, but it doesn't work anyways :
HTML
<div class="confirm-container row">
:before
<div class="col-xs-12">
<button class="btn btn-primary">
<span>Effettua l'ordine</span>
</button>
</div>
::after
</div>
1st try
var = '//*[#id="purchase-app"]/div/div[4]/div[1]/div[2]/div[5]/div/div/button'
WebDriverWait(web, 50).until(EC.element_to_be_clickable((By.XPATH, var)))
web.find_element_by_xpath(var).click()
2nd try
web.find_element_by_class_name('btn btn-primary').click()
3rd try
ActionChains(web).click(web.find_element_by_class_name('btn btn-primary')).perform()

When you are using Explicit wait, try to have a relative xpath :
1st try issue can be resolved by the below code :
WebDriverWait(web, 10).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Effettua l'ordine']/.."))).click()
2nd try web.find_element_by_class_name('btn btn-primary').click() - class name does not accept spaces so, use css selector instead :
web.find_element_by_css_selector('button.btn.btn-primary').click()
same issue with 3rd try.
Update 1 :
The issue is that, the button you are looking is in iframe so you need to switch over it before interaction :
Code :
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src^='/store/purchase?namespace']")))
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-primary"))).click()
Imports :
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

You can try this
from selenium.webdriver import ActionChains
ActionChains(browser).click(element).perform()
while element refer to anything between the start tag and end tag.
as stated in the answer here: https://stackoverflow.com/a/61036237/11884764

Related

How to click on checkbox filter with selenium Python?

I'm trying to click on a checkbox filter on a website with selenium python. This is a part of its HTML code linked to one of the checkbox options.
<div class="shopee-checkbox" bis_skin_checked="1">
<label class="shopee-checkbox__control">
<input type="checkbox" name="" value="Jabodetabek">
<div class="shopee-checkbox__box" bis_skin_checked="1">
<i> </i>
</div>
<span class="shopee-checkbox__label">Jabodetabek</span>
</label>
</div>
I tried following, but it didn't work.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
driver = webdriver.Chrome()
driver.get('https://shopee.co.id/search?keyword=baju%20laki-laki')
time.sleep(5)
driver.find_element(By.XPATH, "//input[#value='JABODETABEK']").click()
I read the answers to similar questions, mostly they suggest using 'id' and 'name' to find the element. However, in this input tag, there are only 'type' and 'value'.
Here is one way to select that checkbox:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
[...]
wait = WebDriverWait(driver, 25)
[..]
wait.until(EC.element_to_be_clickable((By.XPATH, '//span[text()="Jabodetabek"]'))).click()
print('clicked on Jabodetabek')
Selenium documentation can be found here.
#value for the checkbox in the xpath is incorrect. The selenium web locator techniques are case sensitive. So make sure to use exact values while identifying objects. Changing your xpath to below would fix the issue.
driver.find_element(By.XPATH, "//input[#value='Jabodetabek']").click()

function click with selenium without id

I want know how I can click a button in this page here with selenium the code I try is this
import selenium
from selenium import webdriver
from time import sleep
PATH= "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://yopmail.com/it/")
inputsSI= driver.find_element_by_class_name("md").click()
print(inputsSI)
sleep(100)
driver.close()
the error I get is this:
Message: element not interactable
It's because find_element_* methods will return the first occurrence of the element they find. If you see the HTML page there is another div element before the button that has this "md" class and of course it is not the button you are looking for.
You are looking for this buttun :
<div id="refreshbut">
<button class="md" style="border-radius: 20px;"
title="Controllare la posta #yopmail.com"
onclick="{if(chkl())go()}"><i
class="material-icons-outlined f36"></i></button>
<input type="submit" style="display:none;">
</div>
It is wrapped inside a div with id of "refreshbut".
So all you have to do is first get this div by id. Then search for the element which has the "md" class which is indeed the button you are looking for. (you could also get the button with XPATH. it's up to you)
like:
inputsSI = driver.find_element(By.ID, "refreshbut") \
.find_element(By.CLASS_NAME, "md") \
.click()
Note 1: It's better to use raw-string for your PATH variable.
Note 2: I would put the driver.close() statement inside the finally block so that it always runs
To click on the md button use button.md as a selector then wait for the element to be interactable. I don't know what goes in there so I just added a send keys of a.
wait=WebDriverWait(driver,30)
driver.get("https://yopmail.com/it/")
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"#login"))).send_keys('a')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button.md"))).click()
Imports:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

How to use derive an X-Path from a specific HTML attribute to use with Selenium

Background:
I have the following HTML code that I am trying to get a XPATH to use with Selenium
<div class="btn-group">
<a type="button" class="btn btn-primary btn-user" onclick="AiD('182030801')" href="/download.pdf?id=182030801&h=917901e6659ad5eb53970aecf687b53e&u=cache&ext=pdf" target="_blank" style="border-top-left-radius: 3px;border-bottom-left-radius: 3px;">
<i class="fas fa-cloud-download-alt" aria-hidden="true" style="margin-right: 9px;margin-left: 2px;font-size: 25px;vertical-align: middle;color: #119802;"></i>Download ( PDF )
</a>
[...]
</div>
Code:
What have I tried to do with Python's Selenium is the following, however I cannot quiet get it to work without Python throwing an error:
browser.find_element(By.XPATH, "//div[#class='btn-group']/a").click()
browser.find_element(By.XPATH, "//div[#class='btn tn-primary btn-user']").click()
Error:
When I run the above snippet of code, the following error is produced and script crashes thereafter:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//div[#class='btn tn-primary btn-user']"}
Problem:
The error states "no such element", however the element clearly exists "class="btn btn-primary btn-user""
Question:
How can I use Seleniums XPATH to "see" class="btn btn-primary btn-user" and click it to download a PDF?
Link:
PDFDrive
USe Xpath //div/a[#class='btn btn-primary btn-user']
Make sure the intended element is not under an iFrame. If it is then first you need to switch into that iFrame and then have to perform the action
Make sure you are using proper synchrnization and your element is ready. Introduce explicit wait as below:
driver.get('https://www.pdfdrive.com/querying-xml-xquery-xpath-and-sqlxml-in-context-d38665640.html')
WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//div[#class='btn-group']/a"))).click()
time.sleep(10) // it doesn't recommanded to put hardcoded wait but for debugging purpose you can check
Import below packages for this:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
You are using "div" tag but I can see respective class = btn btn-primary btn-user is inside "a" tag
try below code :
browser.find_element(By.XPATH, "//a[#class='btn tn-primary btn-user']").click()
Or you can go with another locator as well.
CSS : a.btn.btn-primarybtn-user
So you need to wait for the element to be clickable. Triggered the download.
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
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
options = Options()
driver = webdriver.Chrome(ChromeDriverManager().install(),options=options)
url = 'https://www.pdfdrive.com/querying-xml-xquery-xpath-and-sqlxml-in-context-d38665640.html'
driver.get(url)
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'a.btn.btn-primary.btn-user'))).click()

Selenium Can't click ajax button

i have a button like this
<button data-control-name="more_comments" id="ember1181" class="comments-comments-list__load-more-comments-button artdeco-button artdeco-button--muted artdeco-button--1 artdeco-button--tertiary ember-view" style="" xpath="1"><!---->
<span class="artdeco-button__text" style="">
Load more comments
</span></button>
and it is loaded with ajax.
my code last code is
browser.implicitly_wait(50)
browser.execute_script("document.getElementsByClassName('comments-comments-list__load-more-comments-button artdeco-button artdeco-button--muted artdeco-button--1 artdeco-button--tertiary ember-view')[1].click();")
i am getting this error oven and over
selenium.common.exceptions.JavascriptException: Message: javascript error: Cannot read property 'scrollIntoView' of undefined
i have tried
implicit_wait
WebElementWait
selection by css selector
by xpath
but still no improvements
Thanks in advance
So Id's are dynamic so you can use below solution to handle 1st comment section from your web page:
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH, "/(//button[#data-control-name='comment'])[1]"))).click()
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Load more comments']"))).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

How to locate an element as per the HTML provided through Selenium and Python

I am trying to click a 'next' button with Selenium in Python, which source code is:
<div class="form-group clearfix">
<button id="experiment-method-previous" type="button" class="btn btn-dark pull-left" ng-click="navigate('run',$event)">Previous</button>
<button id="experiment-method-next" type="button" class="btn btn-primary pull-right" ng-click="navigate('export',$event)">Next</button>
</div>
I use the line:
driver.find_element_by_id('experiment-method-next')
but I get this error:
Unable to locate element: [id="experiment-method-next"]
Same for
driver.find_element_by_class_name('btn btn-primary pull-right')
Unable to locate element: .btn btn-primary pull-right
Any thoughts?
As per the HTML you have shared to invoke click() on the element with text as Next you have to induce WebDriverWait for the desired element to be clickable and you can use either of the following solution:
CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-primary.pull-right#experiment-method-next"))).click()
XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-primary pull-right' and #id='experiment-method-next']"))).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 think your elememnt is inside frame/iframe. To be able to interact with elements inside frame/iframe you have to switch to it's content like this:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//path_to_frame")))
then you can locate your element and interact with it:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "experiment-method-next"))).click()
and when you are done with content inside frame, you have to switch back to default content:
driver.switch_to.default_content()
Note: you have to do some imports:
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
PS: if your elements is not inside frame, then just use WebDriverWait:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "experiment-method-next"))).click()
this will wait at least 10 seconds until element will be clickable and the clicks on it. Hope this helps.
The solution I found is to kill first any previous windows my application opens and switch to the latest one:
current_window = driver.window_handles[1]
driver.switch_to_window(current_window)
Now, the Next Button can be clicked as follows:
driver.find_element_by_id('experiment-method-next').click()
Many thanks to the users Andrei Suvorkov and DebanjanB for their help.

Categories