Finding element with class name with spaces not working (selenium) - python

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")

Related

Keep only an element of a webpage while web-scraping

I am trying to extract a table from a webpage with python. I managed to get all the contents inside of that table, but since I am very new to webscrapping I don't know how to keep only the elements that I am looking for.
I know that I should look for this class in the code: <a class="_3BFvyrImF3et_ZF21Xd8SC", which specify the items in the table.
So how can I keep only those classes to then extract the title of them?
<a class="_3BFvyrImF3et_ZF21Xd8SC" title="r/Python" href="/r/Python/">r/Python</a>
<a class="_3BFvyrImF3et_ZF21Xd8SC" title="r/Java" href="/r/Java/">r/Java</a>
I miserably failed in writing a code for that. I don't know how I could extract only these classes, so any inputs will be highly appreciated.
To extract the value of title attributes you can use list comprehension and you can use either of the following locator strategies:
Using CSS_SELECTOR:
print([my_elem.get_attribute("title") for my_elem in driver.find_elements(By.CSS_SELECTOR, "a._3BFvyrImF3et_ZF21Xd8SC[title]")])
Using XPATH:
print([my_elem.get_attribute("title") for my_elem in driver.find_elements(By.XPATH, "//a[#class='_3BFvyrImF3et_ZF21Xd8SC' and #title]")])
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
Okay, I have made a very simple thing that worked.
Basically I pasted the code on VSCODE and the selected all the occurrences of that class. Then I just had to copy and paste in another file. Not sure why the shortcut CTRL + Shift + L did not work, but I have managed to get what I needed.
Select all occurrences of selected word in VSCode

[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 Select to return a list?

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.

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

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