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.
Related
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.
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
In python we have:
select = Select(driver.find_element_by_id('fruits01'))
But what if I want to have a list of all select tags and not just the first one?
I tried:
select = Select(driver.find_elements_by_id('fruits01'))
But it didn't work for me.
As per the Selenium Python API Docs of Select():
class selenium.webdriver.support.select.Select(webelement)
A check is made that the given element is, indeed, a SELECT tag. If it is not, then an UnexpectedTagNameException is thrown.
So Select() takes a webelement as an argument and you won't be able to pass webelements.
Moreover, each webelement is unique within the DOM Tree. So it's highly unlikely multiple elements would be identified using the same value of id attribute i.e. fruits01.
This usecase
However, considering the usecase as a valid usecase the simplest approach would be similar to #Arundeep Chohan's answer but ideally inducing WebDriverWait for the visibility_of_all_elements_located() as follows:
elements = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.ID, "fruits01")))
for element in elements:
select = Select(element)
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
elems=driver.find_elements_by_id('fruits01')
for elem in elems:
select=Select(elem)
Why not just use a list to loop them ? I don't think you can do it the way you want to.
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
I'm trying to find this element inside a log-in page when a user inputs the wrong password
<div class="form-input-validation is-error" role="alert"></div>
I have tried
driver.find_element_by_css_selector(".form-input-validation.is-error")
but i get a 'no such element: Unable to locate element' error
You can find the element using the syntax, it is basically first waiting(using explicit wait) for the element to be located on the page and after that you can operate on it:
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, "//div[#class='form-input-validation is-error']")))
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 just can substitute the space by a dot . to get the class.
driver.find_element_by_class_name("form-input-validation.is-error")
Class names can't have spaces, the div tag has two classes (separated by a space, .form-input-validation and is-error). Use one or the other, but I would suggest using .is-error because it will only activate if there is an error.
driver.find_element_by_css_selector(".is-error")
Try replacing the Space with a dot.
driver.find_element_by_class_name("form-input-validation.is-error")