how to iterate actions in selenium python - python

I have found webelement using xpath text and performed some actions after finding the webelement. the webelement is in a dropdown. Its a big dropdown with more than 500 options in it. Now I want to perform same set of actions for every webelement which is found using the xpath text I have mentioned.
from selenium import webdriver
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.support.ui import Select
driver = webdriver.Chrome()
driver.get("url")
driver.find_element_by_xpath("//*[contains(text(), 'abc')]")
driver.find_element_by_xpath("//*[#id='btnsubmit']").click()
driver.find_element_by_xpath("//*[#src='Images/pdf.jpg']").click()
with this code I am able to locate the drop down element which has text abc in it and download the pdf file which appears after clicking the submit button. Now I want to loop this and find other elements which have abc in it and download pdfs for each dropdown element.
I have tried this:
element = driver.find_element_by_xpath("//*[contains(text(), 'abc')]")
for i in element :
element.click()
driver.find_element_by_xpath("//*[#id='btnsubmit']").click()
driver.find_element_by_xpath("//*[#src='Images/pdf.jpg']").click()
but this only finding the first element in the dropdown and downloading the pdf. I want to iterate this for all the elements that have abc text in it and download the pdf.
Also tried this:
element = driver.find_elements_by_xpath(".//*[contains(text(), 'abc')]")
for i in element :
element.click()
driver.find_element_by_xpath("//*[#id='btnsubmit']").click()
driver.find_element_by_xpath("//*[#src='Images/pdf.jpg']").click()
it returns an exception that click cannot be performed on list.
can anyone help me with this problem? it would help me reduce a lot of manual work of clicking on each drop down element and downloading the pdf.

You should use i.click instead of element.click there.Or use the below code
elements = driver.find_elements_by_xpath(".//*[contains(text(), 'abc')]")
for element in elements:
element.click()
driver.find_element_by_xpath("//*[#id='btnsubmit']").click()
driver.find_element_by_xpath("//*[#src='Images/pdf.jpg']").click()
Here I have given the name element so it would work.

Related

[python-selenium 4.3.0]How to get element by text under tag a?

i would like to get the element and click on it by the text under tag a:
1791
The text "1791" is what I used to locate this element and click on it.
My code looks like this:
driver.find_element(By.XPATH,("//div[text()='1791']")).click()
and it does not work. My selenium version is 4.3.0, so it does not support command such as find_element_by_xpath. Hence, the answers I found on the internet offers no help.
Thank you!
You are trying to click on the div with the text '1791'.
But in the provided info this text is inside a tag.
Try the following:
driver.find_element(By.XPATH,("//a[text()='1791']")).click()
UPD
Except for the incorrect XPath the problem was in unused WebDriverWait for the element (the expectation for checking that an element is present on the DOM of a page before clicking on it).
Webdriver tries to click an element immediately after opening the desired page, but some elements may not be loaded yet.
The final code will be:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH,("//a[text()='1791']"))).click()
With 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 Can't Find Specific Div Despite Existing in Iframe

I am trying to download the csv file from this link with selenium: https://ourworldindata.org/grapher/annual-co-emissions-by-region and am encountering issues regarding finding the actual elements necessary to download the file. Here is my code so far:
driver.get("https://ourworldindata.org/grapher/annual-co-emissions-by-region")
frame = driver.find_element_by_id("GTM-N2D4V8S")
driver.switch_to.frame(frame)
downloadLink = driver.find_element_by_xpath("/html/body/main/figure/div/div[4]/div/nav/ul/li[4]/a")
driver.execute_script("arguments[0].click();", downloadLink)
Specifically, I am trying to find the second div underneath the element with this css selector body > main > figure > div > div.DownloadTab, which contains the download link. Unfortunatley, while I am able to find this parent element, I am unable to find the div I am looking for. From doing research, I think that this issue might have to do with the iframe, so I am trying to switch it with the code above (although it is not working). This link may be helpful: Selenium can't find elements even if they exist
Thanks so much!
You should wait for the page / elements fully loaded before accessing them and to use the correct locators.
Try this:
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, 20)
driver.get("https://ourworldindata.org/grapher/annual-co-emissions-by-region")
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "li.download-tab-button"))).click()
wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[data-track-note='chart-download-csv']"))).click()

Finding an element using src or href code in python selenium

I am very new to programing and am currently messing around trying to make a bot that will add items to my cart for me. I am using python with the selenium module. The problem I have came across is getting the program to find find an item using with src or href code.
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located(())
)
element.click()
This is the code I am using and I dont know what to put in the brackets to find the src or href. I am wondering which one is easier to use and how to use it in my code. Any advice/criticism at all could help me as I am still learning python. Thank you.
So your question is as follows:
[How] to find find an item using with src or href code[?]
Let's take a code snippet as an example.
This is from the https://www.google.com/ startpage. If you want to find this anchor element with said href attribute by specifically looking for the href url, you need to search with e.g.:
driver.find_element_by_xpath('//a[#href="https://mail.google.com/mail/?tab=rm&ogb"]')
Same goes for your code snippet:
element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, ('//a[#href="https://mail.google.com/mail/?tab=rm&ogb"]'))))
element.click()
Imported modules:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait as wait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

How do i select a button from a table that has identical identifying selectors?

I'm trying to automate signing in on a page where there are two login buttons.
I'm still new with coding in general, but i read that xpath is the way to go.
browser.find_element_by_xpath("//input[#type='submit' and #value='Login']".click()
However, this defaults to the first login button. What selector should I use to select the second button?
This is the the code for the html:
Thanks
If the element more than one, you can use count [] at the end locator like this:
(//input[#type='submit' and #value='Login'])[2]
This is for second element:
browser.find_element_by_xpath("(//input[#type='submit' and #value='Login'])[2]").click()
Many ways you can do that.Since you are selecting last button.You can use index like (//input[#value='Login'])[last()]
Option 1:
browser.find_element_by_xpath("(//input[#value='Login'])[last()]").click()
Option 2
You can take the reference of table cell and xpath would be.
//td[#id='domainlogin_domain_selection']/following::td[1]/input[#value='Login']
So to click on the button.
browser.find_element_by_xpath("//td[#id='domainlogin_domain_selection']/following::td[1]/input[#value='Login']").click()
To handle dynamic element use WebDriverWait and element_to_be_clickable
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"//td[#id='domainlogin_domain_selection']/following::td[1]/input[#value='Login']"))).click()
OR
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH,"(//input[#value='Login'])[last()]"))).click()
Note : You need to import followings when you use WebDriverWait.
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Consider using a css attribute = value selector with * contains operator to target the element by its onclick attribute. Nice and concise and easy to read
browser.find_element_by_css_selector("[onclick*=domainlogin]").click()
Reference:
Attribute selectors
Please try this code in order to click second login Button
browser.find_element_by_xpath("(//input[#value='Login'])[last()]").click()
or
browser.find_element_by_xpath("//td[#id='domainlogin_domain_selection']/following::td[1]/input[#value='Login']").click()
The buttons have different values of the onclick attribute so you can use the following selectors assuming using XPath contains() function:
First button:
//input[#type='submit' and #value='Login' and contains(#onclick, 'userLogin')]
Second button:
//input[#type='submit' and #value='Login' and contains(#onclick, 'domainLogin')]
References:
XPath Tutorial
XPath Axes
XPath Operators & Functions

Selenium can't find element of a link

I am trying to make a program which logs into my depop (A second-hand clothing selling app) and searches for a user. I've managed to make it log in so far. However, it can't find the element of the search button.
I've tried multiple didn't methods but none have worked. Keep in mind I have started learning this today so I am a beginner.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys #allows keyboard to be used
from selenium.webdriver.common.by import By #allow waiting
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as cond
from selenium.webdriver.support import expected_conditions as ec
from selenium.common.exceptions import NoAlertPresentException
from selenium.common.exceptions import TimeoutException
def search():
driver.implicitly_wait(4)
searchbox = driver.find_element_by_name('a')
Message: no such element: Unable to locate element
I just get variations of this error message depending on how I do it.
EDIT:
The element is :
a
< span > Search < /span >
/a
EDIT 2: TO add some more detail onto this to make it easier to understand, when I click on the button, it makes a pull down menu of the actual search bar. So if it eventually finds the element. It gives me this "Message: stale element reference: element is not attached to the page document"
Your find_element_by_name function locates a WebElement by its name attribute, in your case neither span nor a tag have the name.
So you either need to go for find_element_by_tag_name attribute:
driver.find_element_by_tag_name("a")
but be aware that it will return the first link from the DOM, if you need to match the link having inner span with Search text you will need to go for XPath locator like:
driver.find_element_by_xpath("//span[contains(text(),'Search')]/parent::a")
It would be also good to wrap your locator into an Explicit Wait
a is not a name and hence it would not result in finding an element by using method find_element_by_name. Please try using xpath //span[text()='Search'] to find the element search. Please check(in developer console or some other browser extension like xpath, chropath etc) how many elements are being returned using this xpath. If there is just one element, you are good to go. Else, find some other strategy to reach to the desired element before proceeding with performing actions on it.

Categories

Resources