As you've mentioned
The class name has spaces in it, which lead me to use the css_selector
this is right approach, however you should also make sure that one
- One should remove the space and put a
. .represent class in CSS.
So the below code should work:
driver.find_element(By.CSS_SELECTOR, ".btn.btn-alt.see-full-list-btn")
or you can even use it with the tag a
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")
or the recommended solution would be to use with explicit waits:
see_full_list_button = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")))
see_full_list_button.click()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Answer from cruisepandey on Stack OverflowHi all. I'm trying to use Selenium to find an element by CSS selector and although I've tried using the documentation, I think I'm misunderstanding something.
This is what I'm trying:
driver.find_element(By.CSS_SELECTOR,f"img [src='images/icons/new.gif'][alt='Add new item to list']").click()
This is the element I want to find and click:
<img src="images/icons/new.gif" alt="Add new item to list">
The error I get is as follows:
Exception has occurred: NoSuchElementException
Message: no such element: Unable to locate element: {"method":"css selector","selector":"img [src='images/icons/new.gif'][alt='Add new item to list']"}I can see it's on the page, however, so I'm not sure what I'm missing. I can find other items using XPATH and ID so selenium is up and running, just to rule that out. Can anybody suggest anything?
(I'm using selenium 4.8.2 and python 3.11.1, if that helps)
Css Selector button click with selenium (python) - Stack Overflow
python - How to located selenium element by css selector - Stack Overflow
Selenium / Python - Selecting via css selector - Stack Overflow
Selenium | css-selector not found
Videos
As you've mentioned
The class name has spaces in it, which lead me to use the css_selector
this is right approach, however you should also make sure that one
- One should remove the space and put a
. .represent class in CSS.
So the below code should work:
driver.find_element(By.CSS_SELECTOR, ".btn.btn-alt.see-full-list-btn")
or you can even use it with the tag a
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")
or the recommended solution would be to use with explicit waits:
see_full_list_button = WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn")))
see_full_list_button.click()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
There is no necessity to focus on the element HTML after the click is already invoked.
As per the HTML
<a href="#" class="btn btn-alt see-full-list-btn">See Full List</a>
you can use either of the following locator strategies:
Using link_text:
driver.find_element(By.LINK_TEXT, "See Full List").click()Using css_selector:
driver.find_element(By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn").click()Using xpath:
driver.find_element(By.XPATH, "//a[@class='btn btn-alt see-full-list-btn' and text()='See Full List']").click()
Ideally to click on the clickable element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:
Using LINK_TEXT:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.LINK_TEXT, "See Full List"))).click()Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.btn.btn-alt.see-full-list-btn"))).click()Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='btn btn-alt see-full-list-btn' and text()='See Full List']"))).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
driver.find_element_by_css_selector(".test_button4[value='Update']").click()
EDIT:
Because the selector needs a class, id, or tagname, but value.Update by itself is none of these.
.test_button4 provides a classname to match against, and from there, [value='Update'] specifies which particular match(es) to select.
test_button4 = driver.find_elements_by_class_name('test_button4') # notice its "find_elementS" with an S
submit_element = [x for x in test_button4 if x.get_attribute('value') == 'Update'] #this would work if you had unlimited things with class_name == 'test_button4', as long as only ONE of them is value="Update"
if len(submit_element): # using a non-empty list as truthiness
print ("yay! found updated!")
This is something that i hardly ever see anyone document, explain, or use.
(ill use name for example because its simplest)
find_element_by_name() returns a single item, or gives an exception if it doesnt find it
find_elements_by_name() returns a list of elements. if no elements found, the list is empty
so if you do a find_elements_by_class_name() and it returns a list with X entries in it, all thats left at that point to narrow down what you want is either some old fashioned list comprehension ( like how i used in my answer ) or some indexing if you for some reason know which element you want.
also get_attribute() is seriously under-utilized as well. it parses the inside of the elements html by using what is before the = and returns what is after the =
Finding elements by CSS selector is the only way Al Sweigart has taught me. I've tried finding by xpath and by class name and still got an exception although idk if I did those right
here's my code, dont laugh at the website:
from selenium import webdriver
browser = webdriver.Firefox()
browser.get('https://www.barstoolsports.com/shows/call-her-daddy/ask')
elem_for_first_name = browser.find_element_by_css_selector('.quantumWizTextinputPaperinputInput')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/fakename/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 598, in find_element_by_css_selector
return self.find_element(by=By.CSS_SELECTOR, value=css_selector)
File "/home/fakename/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element
'value': value})['value']
File "/home/fakename/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/fakename/.local/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .quantumWizTextinputPaperinputInputI get similar exceptions when trying xpath and class name.
There are a total of 2 (maybe 3) elements I need from this webpage:
-
element for entering your first name
-
element for asking your question
-
(maybe) the submit button
Number 3 might not be that hard since selenium can automatically submit a form after you send the keys. I just haven't gotten to this point yet because I cant find the first 2 elements to begin with.
Please, good pythoners of reddit, help a girl out