How to Handle Changing IDs In XPath? for example : [duplicate] - python

I'm using selenium with python,now I want to locate an element by part of its id name,what can I do?
For example,now I've already located a item by id name coption5 :
sixth_item = driver.find_element_by_id("coption5")
Is there anyway I can locate this element only by using coption?

To find the element which you have located with:
sixth_item = driver.find_element_by_id("coption5")
To locate this element only by using coption you can use can use either of the following Locator Strategies:
Using XPATH and starts-with():
sixth_item = driver.find_element_by_xpath("//*[starts-with(#id, 'coption')]")
Using XPATH and contains():
sixth_item = driver.find_element_by_xpath("//*[contains(#id, 'coption')]")
Using CSS_SELECTOR and ^ (wildcard of starts-with):
sixth_item = driver.find_element_by_css_selector("[id^='coption']")
Using CSS_SELECTOR and * (wildcard of contains):
sixth_item = driver.find_element_by_css_selector("[id*='coption']")
Reference
You can find a detailed discussion on dynamic CssSelectors in:
How to get selectors with dynamic part inside using Selenium with Python?
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
Finding elements by CSS selector with ChromeDriver (Selenium) in Python

Related

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.

How to find element by part of its id name in selenium with python

I'm using selenium with python,now I want to locate an element by part of its id name,what can I do?
For example,now I've already located a item by id name coption5 :
sixth_item = driver.find_element_by_id("coption5")
Is there anyway I can locate this element only by using coption?
To find the element which you have located with:
sixth_item = driver.find_element_by_id("coption5")
To locate this element only by using coption you can use can use either of the following Locator Strategies:
Using XPATH and starts-with():
sixth_item = driver.find_element_by_xpath("//*[starts-with(#id, 'coption')]")
Using XPATH and contains():
sixth_item = driver.find_element_by_xpath("//*[contains(#id, 'coption')]")
Using CSS_SELECTOR and ^ (wildcard of starts-with):
sixth_item = driver.find_element_by_css_selector("[id^='coption']")
Using CSS_SELECTOR and * (wildcard of contains):
sixth_item = driver.find_element_by_css_selector("[id*='coption']")
Reference
You can find a detailed discussion on dynamic CssSelectors in:
How to get selectors with dynamic part inside using Selenium with Python?
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
Finding elements by CSS selector with ChromeDriver (Selenium) in Python

How to use function ends-with in selenium?

I look up the information that lxml does not support xpath2.0 so that it can't use ends-with, so selenium can't use ends-with how to use it or replace ends-with. thank you very much indeed!!!
HTML sample
<span id="xxxxx_close">wwwww</span>
The 'xxxxx' part of #id is random
You can apply an ends-with CSS selector:
By.cssSelector("[id$=_close]")
There's no need of including span tag in css selector search as well.
The ends-with XPath Constraint Function is part of XPath v2.0 but as per the current implementation Selenium supports XPath v1.0.
As per the HTML you have shared to identify the element you can use either of the Locator Strategies:
XPath using contains():
xpath using contains for id attribute:
driver.findElement(By.xpath("//span[contains(#id,'_close')]")).click();
xpath using contains for id and innerHTML attribute:
driver.findElement(By.xpath("//span[contains(#id,'_close') and contains(.,'wwwww')]")).click();
Alternatively, you can also use CssSelector as follows:
css_selector using ends-with (i.e. $ wildcard) clause for id attribute:
driver.find_element_by_css_selector("span[id$='_close']").click();
css_selector using contains (i.e. * wildcard) clause for id attribute:
driver.find_element_by_css_selector("span[id*='_close']").click();

Finding elements by CSS selector with ChromeDriver (Selenium) in 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?

Selenium: finding element by href

How would you find an element in selenium (with python) of the following html:
Login
As per the HTML you have shared to find the element by href you can use either of the following:
css_selector:
driver.find_element_by_css_selector("a[href=/user/login]")
xpath:
driver.find_element_by_xpath("//a[#href='/user/login']")
xpath (Multiple Attributes):
driver.find_element_by_xpath("//a[#href='/user/login' and text()='Login']")

Categories

Resources