Finding elements by CSS selector with ChromeDriver (Selenium) in Python - python

I'm using ChromeDriver of Selenium with Python and I'm trying to find a button on my page that has the following HTML:
<input id="j_id0:SiteTemplate:j_id255:new" type="submit" name="j_id0:SiteTemplate:j_id255:new" value="New" class="kbutton-white">
The only thing I know being constant is the id and name ending with "new" and I'm trying to use the following code to identify and click that element:
test_runner.driver.find_element_by_css_selector('[id*=new]').click()
However, I get this error when I run the code:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id*=new]"}
What's my mistake here?
Update: This element was inside an iframe and I had to switch to the iframe before trying to find the element. Please see comments for the answer.

As per the HTML you have shared to invoke click() on the desired element you can use the following css_selector :
driver.find_element_by_css_selector("input.kbutton-white[id$='new'][name$='new'][value='New']").click()
Explaination :
.kbutton-white : The class attribute.
id$='new' : id attribute ends with new
name$='new' : name attribute ends with new
value='New' : The value attribute.
But it seems the element is dynamic so you may need to induce WebDriverWait as follows :
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.kbutton-white[id$='new'][name$='new'][value='New']"))).click()
References
You can find a couple of relevant detailed discussions in:
Java Selenium webdriver expression finding dynamic element by ccs that starts with and ends with
How to click a dynamic link with in a drupal 8 website using xpath/css selector while automating through Selenium and Python
How to get selectors with dynamic part inside using Selenium with Python?

Related

How to click on a webpage element with Python

Imgur Web Element
I want to write a line of code that clicks on the ellipsis on the webpage. I've attached the element description.
I can't share the webpage as it is password protected
Here's what I tried:
element = driver.find_element_by_css_selector('.fas.fa-ellipsis-v')
element.click()
I am expecting the ellipsis to pop open but i get the following error:
Message: no such element: Unable to locate element: {"method":"css selector","selector":".fas.fa-ellipsis-v"}
First of all, please, do not use images when your want a code review or help, it is more easier to help with raw code.
In that case:
Message: no such element: Unable to locate element: {"method":"css selector","selector":".fas.fa-ellipsis-v"}
Try to use this code below instead of driver.find_element_by_css_selector([...]) :
WebDriverWait(your_driver, your_timeout).until(EC.visibility_of_element_located((By.CLASS_NAME, your_locator)))
or
WebDriverWait(your_driver, your_timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, your_locator)))
After the WaitDriverWait, use your find and click code.
If you need more help locating elements by, try look the Selenium Docs.
It worked by using the following line:
driver.execute_script("arguments[0].click();", element)

Selenium/Python Unable to use `:contains()` in CSS_SELECTOR [duplicate]

This question already has answers here:
selenium.common.exceptions.InvalidSelectorException with "span:contains('string')"
(2 answers)
Closed 1 year ago.
When I try to use :contains in Selenium's By.CSS_SELECTOR, such as
presence = EC.presence_of_element_located((By.CSS_SELECTOR, ".btn:contains('Continue Shopping')"))
or
presence = EC.presence_of_element_located((By.CSS_SELECTOR, ".btn\:contains('Continue Shopping')"))
or
presence = EC.presence_of_element_located((By.CSS_SELECTOR, ".btn\\:contains('Continue Shopping')"))
the Python program crashes with the error
Exception: Message: invalid selector: An invalid or illegal selector was specified
(Session info: chrome=95.0.4638.54)
Is it possible to use :contains in Selenium? The CSS selector
$('.btn:contains("Continue Shopping")')
works fine in Chrome's JS console.
Using Chrome 95.0.4638.54, ChromeDriver 95.0.4638.54, Python 3.10 on Ubuntu 20.04.
The selector :contains('text') is a jQuery selector, not a valid CSS selector like Selenium is expecting. I'm assuming the reason it works on the page via Chrome's DevTools console is because the page has jQuery defined on it.
Unfortunately, I do not believe you can directly select an element via its text using a CSS selector (link).
You have two options as far as I can see:
Alter your selector to be class or ID based (easiest)
Create a Selenium utility to run a JS script that uses this jQuery selector; e.g. execute_script("jQuery(" + id + ":contains('" + text + "')", id, text)
As mentioned by Aspok your CSS locators are not a valid CSS locators.
To locate element based on it text you can use XPath locator, something like:
//*[contains(#class,'btn') and(contains(text(),'Continue Shopping'))]
In case btn is the only class name attribute of that element your XPath can be
//*[#class='btn' and(contains(text(),'Continue Shopping'))]
As explained by #aspok, it is not a valid css selector.
In case you would like to have XPath for the same, and .btn is class and have text/partial text
Continue Shopping
You can try the below XPath :
//*[contains(text(),'Continue Shopping')]
or
//*[contains(text(), 'Continue Shopping') and contains(#class, 'btn')]
Please check in the dev tools (Google chrome) if we have unique entry in HTML DOM or not.
xpath that you should check :
//*[contains(text(), 'Continue Shopping') and contains(#class, 'btn')]
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the xpath and see, if your desired element is getting highlighted with 1/1 matching node.
Also, Just letting you know that, //* can be replaced by tag name, if you found multiple matching nodes.

Unable to locate element with xPath

I'm literally going crazy to find an element in a specific web page. It's an "Enter" button but I haven't been being able to locate it.
ERROR MESSAGE:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"input"}
(Session info: chrome=86.0.4240.111)
I'm going to share with you the possible selectors by ChroPath Extension:
HTML INSPECT CODE "ENTER" BUTTON:
<input type="button" value="Entra" onclick="parent.location.href='site.site.site'">
1°ATTEMPT - PYTHON CODE WITH REL XPATH:
elem = browser.find_element_by_xpath('//body[1]/div[1]/div[1]/div[2]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/table[1]/tbody[1]/tr[3]/td[1]/input[1]')
2°ATTEMPT - PYTHON CODE WITH ABS XPATH:
elem = browser.find_element_by_xpath('/html[1]/body[1]/div[1]/div[1]/div[2]/div[1]/table[1]/tbody[1]/tr[1]/td[2]/table[1]/tbody[1]/tr[3]/td[1]/input[1]')
I have checked if there were any iframes, but I can't find them.
Please, help me.
I agree with #josifoski. It is better to use custom xpath than autogenerated by browser. So in your case try to use the following xpath:
xpath = '//input[#type="button"][#value="Entra"]'
It will be easier to understand and support.
I got it.
I was wrong when I told you that there weren't any iframes in the source code.
There are 2 ones!
So this is the right code to click the "Enter" button:
browser.switch_to.frame(0)
browser.switch_to.frame(1)
elem = browser.find_element_by_css_selector('td:nth-child(2) input')
elem.click()
To figure out, I recorded my steps with Selenium Ide for Chrome Browser, then I exported the python source code and I saw 2 switch_to.frame functions; then I did 2 plus 2...
Like you can see, at the end, I used a css_selector argument based on the recorded source code that I had exported.
I hope it's clear and useful for other people.
Thank you so much for your help and sorry for the incomplete information.
Can you try this
xpath = '//input[#value="Entra"]'

Selenium WebDriver - cannot locate some elements inside iFrame

I'm running test scripts on the Shopify checkout page, and while I am able to switch to the iFrame and get the Card Number element, the same approach doesn't seem to work for the other input elements (id='expiry', id='name' etc)
Form screenshot
Inspect iFrame screenshot
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#class='card-fields-iframe']")))
element12 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.ID,'number')))
element12.click()
element12.send_keys('1111222233334444')
Have also tried driver.switchTo().defaultContent() and switching back to iFrame again, but same error
element13 = WebDriverWait(driver,20).until(EC.presence_of_element_located((By.ID,'expiry')))
element13.click()
element13.send_keys('1220')
Here's the error I get for element13.
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element is not clickable at point (489, -1)
Found out the issue - the elements were in separate iFrames. Modified my code to retrieve the iFrames using xpath and a partial match on the different id fields

How do I click a button using Selenium in Python?

I'm trying to crawl review data on an app from a Google Play website page using Python and Selenium. What I'm trying to do here is to click the "Full Review" button to see the entire text of each review.
But I keep running into these errors each time:
ElementNotInteractableException: Message: element not interactable
or
AttributeError: 'list' object has no attribute 'click'
or
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".LkLjZd ScJHi OzU4dc "}
The element for the button is this:
<button class="LkLjZd ScJHi OzU4dc " jsaction="click:TiglPc" jsname="gxjVle">Full Review</button>
The xpath for the button is this:
//*[#id="fcxH9b"]/div[4]/c-wiz/div/div[2]/div/div[1]/div/div/div[1]/div[2]/div/div[26]/div/div[2]/div[2]/span[1]/div/button
And this is the code I'm using for xpath:
full_review = driver.find_elements_by_xpath('//*[#id="fcxH9b"]/div[4]/c-wiz/div/div[2]/div/div[1]/div/div/div[1]/div[2]/div/div[26]/div/div[2]/div[2]/span[1]/div/button')
full_review.click()
I can't find the button by class name, xpath or anything.
Could anyone help me figure out this problem? In addition, is it possible to find the element by jsname?
I would really appreciate if you could help.
Avoid using xpath whenever possible, it's the most brittle selector.
id > CSS > Xpath
For your button, this css selector should work:
button[jsname='gxjVle']
You'll probably need to specify the child as that probably won't be unique
Your XPath selector is a little bit flaky, you can simplify it to be something like:
//button[text()='Full Review']
You're using the wrong function, if you're looking for a single unique element you should be using WebDriver.find_element_by_xpath one, mind that element, not elements
It's better to use Explicit Wait just in case element is not immediately available in DOM (for example if you're testing application built using AJAX technology)
Assuming all above:
full_review = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[text()='Full Review']")))

Categories

Resources