Select a checkbox with variables wih Selenium - python

The address below is the xpath address.
//label[#for="check54490"])
The check box is checked when typed as below.
driver.find_element_by_xpath('//label[#for="check54490"]').click()
However, there are many check boxes that need to be checked, so I am going to make variables and check them.
I made a variable as below, but an error occurs.
umber = [54490]
for num in umber:
elem = f'//label[#for="check{num}"]'
elm2 = f"'{elem}'"
xpath = elem2
driver.find_element_by_xpath(xpath).click()
the error message is as follows.
Is the approach good or is it impossible in the first place?
Please give me some advice.
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression driver.find_element_by_xpath('//label[#for="check1000054759"]').click() because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string 'driver.find_element_by_xpath('//label[#for="check54490"]').click()' is not a valid XPath expression.
(Session info: chrome=90.0.4430.85)

Instead of doing it in for loop you can directly do it in the xpath for single value as below -
driver.find_element_by_xpath("//label[#for='check" + str(umber[0]) + "']")
Now since you have asked how you can do it in case of multiple values consider the following code example -
umber = [54490, 54490]
for num in umber:
driver.find_element_by_xpath("//label[#for='check" + str(num) + "']").click()
OR you can have each number in different variable -
xbuttonNum = '54490'
ybuttonNum = '54491'
zbuttonNum = '54521'
driver.find_element_by_xpath("//label[#for='check" + xbuttonNum + "']").click()
driver.find_element_by_xpath("//label[#for='check" + ybuttonNum + "']").click()
driver.find_element_by_xpath("//label[#for='check" + zbuttonNum + "']").click()
Alternatively you can customize your xpath unique for all the elements and iterate over them all at once like -
AllElementwithCheckString = driver.find_elements_by_xpath("//label[starts-with(#for,'check')]")
for elem in AllElementwithCheckString:
elem.click()

Related

How to iterate over xpath and check if image exists and perform operation based on that

Image
As you can see in the image, I have 2 solutions (solution 1 is for a flight and solution 2 is for a hotel)
I want to iterate over each solution using XPATH. I am successful in that. I want to check the image returned on iteration.
My code is somewhat like this:
if select_solution.size != 0:
print(str(i) + " solution selected")
if '/assets/review/images/nodes/icon-plane.png' in driver.find_element(By.XPATH, config.RT_flightImage_check_Xpath.format(i)).get_attribute("src"):
result['Solution ' + str(i)] = {}
print("Solution is for Flight")
print("**********************")
returned_solution = 'Flight'
result['Solution ' + str(i)]['Returned Solution'] = returned_solution
elif 'assets/review/images/nodes/icon-hotel.png' in driver.find_element(By.XPATH, config.RT_HotelImage_check_Xpath.format(i)).get_attribute("src"):
result['Solution ' + str(i)] = {}
print("Solution is for Hotel")
print("**********************")
returned_solution = 'Hotel'
result['Solution ' + str(i)]['Returned Solution'] = returned_solution
Result:
Total number of Solutions found: 2
1 solution selected
Solution is for Flight
**********************
--------
2 solution selected
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//hgb-content-view[1]/div[1]/div[1]/div[2]/div[1]/hgb-flight-content-view[1]/div[1]/div[2]/div[1]/img[1]"}
(Session info: chrome=103.0.5060.134)
The issue that i am facing is that when it iterates the 1st time, it finds the flight and does the necessary operation, but during the second iteration it fails because it does not find the flight (No such element exception).
How do I make sure that it goes to the elif and not exit cause the flight xpath is not found in the selected iteration?
try:
elem=driver.find_element(By.XPATH, config.RT_flightImage_check_Xpath.format(i))
except Exception as e:
print(str(e))
elem=[]
pass
Try except and catch the error and display it. Then do it for the other one.
if len(elem)!=0 and '/assets/review/images/nodes/icon-plane.png' in elem.get_attribute("src"):
#your code
elif len(elem2)!=0 and 'assets/review/images/nodes/icon-hotel.png' in elem2.get_attribute("src"):
#your code
This actually worked. Had to tweak it a little instead of find_element, I used find_elements
try:
flight_element=driver.find_elements(By.XPATH, config.RT_flightImage_check_Xpath.format(i))
except Exception as e:
print(str(e)) elem=[] pass
if len(flight_element) != 0 and '/assets/agent/icons/transaction/plane.svg' in driver.find_element(By.XPATH, config.AA_flight_icon_Xpath.format(i)).get_attribute("svg"):
and this way, in second iteration i was able to find the hotel and get the desired result

Use variable to find xpath selenium not working

I am working on web automation with selenium and I need to find an element with the xpath. This by itself is not a problem but the code needs to run multiple times and when it does that the HTML xpath changes. This is also not a problem. I have used simple math to get the new xpath every time.
The xpathes look like this
1. run: '//*[#id="input-text-3"]'
2. run: '//*[#id="input-text-5"]'
3. run: '//*[#id="input-text-7"]' etc.
I solved this problem using this code:
y = 1
#Corme browser already defined and on website
while True:
mathop1 = y*2 + 1
xxpath = ""'//*[#id="input-text-' + str(mathop1) + '"]'""
xxpath1 = "'" + str(xxpath) + "'"
print(xxpath1)
Bezeichnung = driver.find_element_by_xpath(xxpath1)
Bezeichnung.send_keys(file1name)
y = y + 1
What this does is that every time the program loops it updates y so the xpath will be correct. I tried using the output from xxpath1 to find the element like you normally would and it works fine however as soon as I use the variable it does not work. Specifically, the problem is this I can't use the variable.
Bezeichnung = driver.find_element_by_xpath(xxpath1)
why does this not work?
First of all, I guess you have to put a wait condition there.
Also, I do not understand why are you using so much strings inside string and converting string to string again, so I removed that
y = 1
#Corme browser already defined and on website
while True:
mathop1 = y*2 + 1
xxpath = '//*[#id="input-text-{}"]'.format(mathop1)
Bezeichnung = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, xxpath)))
Bezeichnung.send_keys(file1name)
y = y + 1

Getting text? from full xpath quick question

Relatively new in programming, doing Python with Selenium and Xpath
this is from this website:https://www.marketbeat.com/stocks/NASDAQ/AMZN/earnings/
what I am trying to do is copy the dates of the past earnings.
Problem is it is in the table and it also has tag.
I have this full Xpath:
/html/body/div[1]/main/article/form/div[8]/div[2]/div[2]/div/div[5]/div/table/tbody/tr[2]/td[1]
and upon inspection it shows this
< td data-sort-value="20201027000000">10/27/2020 < / td >
I am trying to get the 10/27/2020 out from here but I don't know how to.
It is easy when it is just the < td >$1.53< /td > where just giving the full xpath and then doing a .text on it gives me the text.
point is how do I get 10/27/2020. I would suspect that I would have to go over data-sort-value="" part.
Here is what I have :
stringeEPSxpath = """/html/body/div[1]/main/article/form/div[8]/div[2]/div[2]/div/div[5]/div/table/tbody/tr[""" + row + """]/td[1]"""
Date = stringeEPSxpath.text
(the row part is just me iterating the website page through a loop no problem there.)
For the rest of my code it has been pretty simple :
stringeEPSxpath = """/html/body/div[1]/main/article/form/div[8]/div[2]/div[2]/div/div[5]/div/table/tbody/tr[""" + row + """]/td[3]"""
stringEPSxpath = """/html/body/div[1]/main/article/form/div[8]/div[2]/div[2]/div/div[5]/div/table/tbody/tr[""" + row + """]/td[4]"""
elem = driver.find_element_by_xpath(stringeEPSxpath)
elem2 = driver.find_element_by_xpath(stringEPSxpath)
fix1 = (elem.text).replace(')','')
fix2 = (elem2.text).replace(')','')
eps1 = fix1.replace('(','-')
eps2 = fix2.replace('(','-')
As you can see above all I had to do was set a variable to it then use .text to convert it to a string. But now that does not work for dates.
The end result is the error of AttributeError: 'str' object has no attribute 'text' which I would suspect is because of the data-sort-value="20201027000000" part.
In this code stringeEPSxpath is string, not WebElement.
stringeEPSxpath = """/html/body/div[1]/main/article/form/div[8]/div[2]/div[2]/div/div[5]/div/table/tbody/tr[""" + row + """]/td[1]"""
Date = stringeEPSxpath.text
You can try this one:
from selenium.webdriver.common.by import By
element = driver.find_element(By.XPATH,"//td[#data-sort-value='20201027000000']")
Date = element.text
Forgot driver.find_element_by_xpath(stringeEPSxpath) which actually uses xpath. Since I copy and pasted from my other program I guess I deleted too much and completely forgot to add in the driver.findxpath.

Python/Selenium: insert an iterator in the Xpath

I'm trying to insert the variable "i" on my Xpath but I'm hitting a wall.
This is my code:
for i in range(len(results_nbr)):
xpath = "//*[#id='w1']/div["
xpath += int(i)
xpath += "]/div/div[2]/h3"
elem = driver.find_element_by_xpath(xpath)
elem.click()
time.sleep(1)
I'm using selenium and it works fine if I have the variable in the code as below:
elem = driver.find_element_by_xpath('//*[#id="w1"]/div[1]/div/div[2]/h3')
What is wrong with my code please? I tried int(i) and str(i) with same result.
I appreciate your help. Thanks
First point: use string formatting. There are a lot of available options in Python:
- xpath = '//*[#id="w1"]/div[%s]/div/div[2]/h3' % i
- xpath = '//*[#id="w1"]/div[{}]/div/div[2]/h3'.format(i)
- xpath = f'//*[#id="w1"]/div[{i}]/div/div[2]/h3' # in Python 3.6 and later
Second point: in XPath indexing starts from 1. So div[0] won't work. Try
for i in range(1, len(results_nbr) + 1):
...

Click on Javascript Link using Selenium Python

I need to click on the "Visualizar cruzeiros" button on this site: https://www.disneytravelcenter.com/MIN-000000000031063/sites++disney-cruise-line++cruises-destinations++alaska++view-sailings++view-sailings/
Unfortunately, I cannot do it by simply using:
visualizar = driver.find_element_by_css_selector('#jb-card-txt-blk-redirect-link-zone-' + zona + 'night-' + str(c)+ '.redirectLink')
visualizar.click()
Or using:
visualizar= driver.find_element_by_class_name('redirectLink')
visualizar.click()
Or using:
visualizar= driver.find_element_by_xpath('//*[#id="jb-card-txt-blk-redirect-link-zone-' + zona + 'night-' + str(c) +'"]')
visualizar.click()
How am I supposed to click on this button then?
OBS: The "zona" and str(c) are loop variables, but they don't change the result of the code, actually.
Have you tried using xpath //a[contains(text(),'Visualizar cruzeiros')? This should return more than one element, you need to get the second one.
Try to write a test case with selenium IDE, it may give you a hint how to access the element.
Found out the answer to my problem:
button = driver.find_elements_by_xpath('//*[#id="jb-card-txt-blk-redirect-link-zone-' + zona + 'night-' + str(c) + '"]')[2]
button.click()

Categories

Resources