The beginning of the CSS Selector is wrong.
Searching for .freesim-text-last button span you will find two elements.

Pick the one which you're trying to reach using the follow:
.freesim-text-last button span:nth-of-type(1)
for the first element and
.freesim-text-last button span:nth-of-type(2)
for the second element.
Answer from João Farias on Stack ExchangeThe beginning of the CSS Selector is wrong.
Searching for .freesim-text-last button span you will find two elements.

Pick the one which you're trying to reach using the follow:
.freesim-text-last button span:nth-of-type(1)
for the first element and
.freesim-text-last button span:nth-of-type(2)
for the second element.
In situations like this, you should try working up and seeing if the more easily available elements can be found instead. A fairly standard way check is to confirm the title element is found and correct.
Afterwards I would consider a timing issue. Has the DOM fully loaded before searching for this element? Selenium comes with different waits (implicit, explicit) which you can use to wait for certain elements to be loaded. A quick (and usually bad) way of testing this would just be to add:
time.sleep(5)
After you get open the browser, and before the element you're looking for, to give it time to load.
python - Selenium can't find xpath or css selector - Stack Overflow
button - click() on css Selector not working in Selenium webdriver - Stack Overflow
java - CSS Locator with contains() InvalidSelectorException using Selenium WebDriver - Stack Overflow
Css Selector button click with selenium (python) - Stack Overflow
It might not work finding the element because it's not visible in UI - it is loaded but not visible, the easiest way is to move to that element and click on it.
next_button = driver.find_element_by_css_selector('[aria-label=\'Next\']')
actions = ActionChains(driver)
actions.move_to_element(next_button).perform()
next_button.click()
next_button = driver.find_element_by_xpath('//button[@class="css-1lkjxdl eanm77i0"]').click()
You was using xpath variable and finding it by css. for css selector you have to use the class (.css-1lkjxdl) and use the above code it will work and accept the answer. Thanks!!
i would inject piece of js to be confident in resolving this issue:
first of all locate element using DOM (verify in firebug):

public void jsClick(){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("document.getElementsByTagName('button')[0].click();");
js.executeScript(stringBuilder.toString());
}
jsClick();
from the retrospective of your element it be like:
....
stringBuilder.append("document.getElementsByTagName('input')[0].click();");
....
Please, note: document.getElementsByTagName('input') returns you an array of DOM elements. And indexing it properly e.g. document.getElementsByTagName('input')[0], document.getElementsByTagName('input')1, document.getElementsByTagName('input')[2]....
,etc you will be able to locate your element.
Hope this helps you. Regards.
Please use the below code.
driver.findElement(By.cssSelector("input[value=\"Search\"]")).click();
It works for me. And make sure that the name is "Search", coz it is case sensitive.
Thanks
The main problem is at this line:
driver.findElement(By.cssSelector("a:contains('About Google')"));
css doesn't maintain contains() for Selenium WD - See here.
For using contains() you have to use Xpath.
With Xpath your locator will be:
//a[contains(text(), 'About Google')]
and for driver it will be as:
driver.findElement(By.xpath("//a[contains(text(), 'About Google')]"));
For finding links with Selenium you can use:
driver.findElement(By.linkText("your link name here"));
It is limitation of CSS selectors compare to Xpath:
- you can't take parent element with CSS selectors (Xpath has XPath axes)
- you can't use contains (it is only XPath privilege).
BTW
For processing Xpath locators from page you able to use extension for Firefox browser:
FirePath
Xpath Checker
CssSelector does not work in scripting but it works in selenium IDE.
It's also not good to work on sites like gmail.
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
When using multiple class names for the same tag within a CSS Selector, they must be separated by a dot instead of a space. Here's the correct way to express your third one:
(By.CSS_SELECTOR, ".ui.dropdown.selection")
OR
(By.CSS_SELECTOR, "div.ui.dropdown.selection").
As for the fourth one, you can't use By.CLASS_NAME with multiple class name components. You would have to pick one, but since that probably won't give you a unique selector, you'll be better off using one of the other ways to form a selector.
@Michael
(By.CSS_SELECTOR, ".ui.dropdown.selection")
(By.CSS_SELECTOR, "div.ui.dropdown.selection")
Both don't work - selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
But notice that there is only 1 element because this works:
(By.XPATH, "//div[@class='ui dropdown selection']")
and len(element) = 1
You probably don't need LINQ for this. You can use the :not() pseudo-class, one for each value you want to exclude (note the *= in each negation; I'm assuming substring matches here):
driver.FindElements(By.CssSelector("a[href]:not([href*='logoff']):not([href*='client'])"))
An exception is if you have a dynamic list of values that you want to exclude: you can either build your selector programmatically using string.Join() or a loop and then pass it to By.CssSelector(), or you can follow Richard Schneider's answer using LINQ to keep things clean.
After using CSS to get the elements then use LINQ to filter on the href.
Using System.Linq;
string[] blackList = new string[] { "logoff, "client",... };
string[] urls = driver
.FindElements(By.CssSelector("a[href]"))
.Select(e => e.GetAttribute("href"))
.Where(url => !blackList.Any(b => url.Contains(b)))
.ToArray();
Checking the URL is case-sensitive, because that is what W3C states. You may want to change this.
I'm following the Automate The Boring Stuff course on Udemy by u/AlSwiegart. I'm on section 13 Web Scraping - 41. Controlling the Browser with the Selenium Module. I think possibly that some of the Selenium module's input syntax/requirements have changed since the video tutorial was made.
I've downloaded the chromedriver and geckodriver and added them to PATH in Windows 10. The following works to open both browsers.
driver.get('insert URL here')I'm trying to assign a CSS Selector to a variable. The code in the video is
elem = driver.find_element_by_css_selector('insert copied css selector path here')This gives the following error:
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
elem = driver.find_element_by_css_selector('.main > div:nth-child(1) > div:nth-child(3) > center:nth-child(1) > a:nth-child(1) > img:nth-child(1)')
File "C:\Users\Gaz\AppData\Local\Programs\Python\Python38-32\lib\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 "C:\Users\Gaz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 976, in find_element
return self.execute(Command.FIND_ELEMENT, {
File "C:\Users\Gaz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "C:\Users\Gaz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Failed to decode response from marionetteI looked on the Selenium.dev website and the code there differs slightly. So I tried:
elem = driver.find_element(By.CSS_SELECTOR, "Insert copied CSS Selector Path Here")
This gives the following error:
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
elem = driver.find_element(By.CSS_SELECTOR, ".main > div:nth-child(1) > div:nth-child(3) > center:nth-child(1) > a:nth-child(1) > img:nth-child(1)")
NameError: name 'By' is not definedAny help is appreciated.
You don't need to (and shouldn't) include style=display:... in your locator to determine visibility. Selenium does that for you when you use .Displayed or use ExpectedConditions and wait for visible. Just locate the element normally, e.g. both of your elements have an ID so use By.Id("page_progress"), like
wait.Until(ExpectedConditions.ElementIsVisible(By.Id("page_progress"));
and Selenium will take care of the rest.
The wrong comparison operator is being used in the CSS selector.
The ~= operator must exactly match the value of the attribute.
Either add the block part of the attribute value, or change the comparison operator to ^=.
By.CssSelector("#page_progress[style^='display:']")
More info: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors