The answer is No, You can't use driver.find_element_by_class_name () or driver.find_elements_by_class_name () with multiple class names. It accepts only single class name.
However, you can use find_elements_by_xpath or find_element_by_css_selector method to achieve finding element with multiple class names.
for example below code will find element on google website using two different class names.
url= "http://google.com"
driver = webdriver.Chrome()
driver.get(url)
driver.find_elements_by_xpath("//*[@class='sfibbbc' or @class='jsb']")
# Following line will result in error
driver.find_elements_by_class_name("sfibbbc jsb")
Answer from Gaurang Shah on Stack OverflowUsing CSS selector for find element with multiple class in Selenium in Python - Stack Overflow
automated testing - How to select element by class when multiple elements match? - Software Quality Assurance & Testing Stack Exchange
finding items with selenium by CSS selector using multiple attributes
Selenium CSS selector by id AND multiple classes - Stack Overflow
Videos
To select the div with the class you can use css (preferred for readability)
BY.css
Example
driver.find_element(By.CSS, 'div.dept-time')
or xpath
BY.xpath
Example
driver.find_element(By.XPATH, '//div[@class=dept-time]
or if there are multiple classes for that element, use
contains
Example
//div[contains(@class, 'dept-time')]
If more than 1 div element with that class exist and you want the first one you can also use:
[1]
Example (XPATH)
//div[@class='dept-time'])[1]
Example (CSS)
div.dept-time:first
Using css selectors, instead of class, the syntax to select the tag with a specific class/attribute is tag[attribute='value']. So in your case:
[element.text for element in self.browser.find_elements(By.CSS_SELECTOR, "div[class='dept-time']")]
More information on css selectors: https://www.w3schools.com/cssref/css_selectors.asp
Hi 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)
Actually the two are quite different selectors.
Here is your cssSelector:
div#someId.aClass.andAnother input[type=text]
But what you really wanted to write was:
div#someId .aClass.andAnother input[type=text]
notice the space between ID and class. you need that.
findElement() finds an element in the current context, which means your first snippet of code is really finding an element that matches .aClass.andAnother input[type=text], which is contained within #someId. The element with that ID may or may not contain the two classes; WebDriver doesn't assume you're referring to the same element; it just finds the input as long as its ancestors are #someId and .aClass.andAnother.
This is completely different from div#someId.aClass.andAnother input[type=text], which finds any input[type=text] within div#someId.aClass.andAnother only (i.e. it's a div that contains both the ID and the classes).
I don't think barak manos's answer has fully explained it.
Imagine we have few elements as the followings:
<div class="value test"></div><div class="value test "></div><div class="first value test last"></div><div class="test value"></div>
How XPath matches
Match only 1 (exact match), barak's answer
driver.findElement(By.xpath("//div[@class='value test']"));Match 1, 2 and 3 (match class contains
value test, class order matters)driver.findElement(By.xpath("//div[contains(@class, 'value test')]"));Match 1, 2, 3 and 4 (as long as elements have class
valueandtest)driver.findElement(By.xpath("//div[contains(@class, 'value') and contains(@class, 'test')]"));
Also, in cases like this, Css Selector is always in favor of XPath (fast, concise, native).
Match 1
driver.findElement(By.cssSelector("div[class='value test']"));Match 1, 2 and 3
driver.findElement(By.cssSelector("div[class*='value test']"));Match 1, 2, 3 and 4
driver.findElement(By.cssSelector("div.value.test"));
Try this:
test = driver.findElement(By.xpath("//div[@class='value test']"));
I'm having trouble clicking a certain button. It appears all the buttons have the same class name so I can't use that. Any help would be so much appreciated.
Website Code:
https://imgur.com/a/54juO4V
I've tried the following
browser.find_element_by_link_text('New Registration').click()
browser.find_element_by_xpath("//*[contains(text(), 'main content')]").click()
browser.find_element_by_css_selector('.row:nth-child(2) .btn').click()
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
This By.classname("btn btn-xs btn-custom") will not work, as it contains multiple spaces which means it is combination of 3 classes.
You will have to switch to css selector or xpath , I do not know why you have mentioned that you do not want to use both of them.
However, If you are interest to use css selector :
You can try this :
By.cssSelector("btn.btn-xs.btn-custom")
If you go by precedence :
- ID
- name
- classname
- linkText
- partialLinkText
- tagName
- css selector
- xpath
The class attribute of this element...
<button style="padding:2px 7px; background-color:#4caeea"
class="btn btn-xs btn-custom" </button>
contains multiple classnames.
Using By.classname("btn btn-xs btn-custom") you won't be able to locate it as:
Find elements based on the value of the "class" attribute. If an element has multiple classes, then this will match against each of them. For example, if the value is "one two onone", then the class names "one" and "two" will match.
As per your requirement, avoiding the xpath & css-selectors you still can use classname but the element may not be the first/only match. As an example:
By.classname("btn")//would match all the elements which contains the classname btnBy.classname("btn-xs")//would match all the elements which contains the classname btn-xsBy.classname("btn-custom")//would match all the elements which contains the classname btn-custom
As an alternative, you can also use the following Locator Strategies:
cssSelector:
By.cssSelector("button.btn.btn-xs.btn-custom")xpath
By.xpath("//button[@class='btn btn-xs btn-custom']")