How to find element by XPATH using variable Selenium - python

I'm trying to parse some elements using XPATH
This is my python code:
driver.get("http://watir.com/examples/shadow_dom.html")
shadow_host = driver.find_element(By.XPATH, '//*[#id="shadow_host"]')
shadow_root1 = shadow_host.shadow_root
shadow_host1 = shadow_root1.find_element(By.XPATH, '/span')
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument: invalid locator
I know that I can use CSS Selectors, but I want to use it in case there aren't any CSS Selectors. Can you help me, how to write shadow_host1 correctly using XPATH? Thanks

You cannot use XPATH locators with shadow root. You can use CSS LOCATORS instead (when on a Chrome/chromedriver setup), or alternatively (when using a Firefox/geckodriver setup) use javascript selectors (querySelector).

Related

Unable to locate element with relative XPATH or CSS selector, but absolute XPATH is located and clickable in python selenium

I'm struggling with locating an element to click. Here's what I am working with:
I'm trying to locate the element with the a href link. I've tried the following:
driver.find_element(By.CSS_SELECTOR,'a[href="/collections/e-coated-kettlebells/products/28kg-kettlebell"]').click()
driver.find_element(By.XPATH,'//div//a[#href="/collections/e-coated-kettlebells/products/28kg-kettlebell"]').click()
driver.find_element(By.XPATH,'//a[#href="/collections/e-coated-kettlebells/products/28kg-kettlebell"]parent::div').click()
The absolute XPATH is the only thing that works
driver.find_element(By.XPATH,'//*[#id="shopify-section-collection-template"]/div/div/div/div[25]/a').click()
The a href contains the 28kg element that I need to use. What am I missing in writing this CSS / XPATH?
Thanks!
enter link description here
Is the website
These are unique locators for that element.
XPath:
"//div/a[contains(#href,'28kg-kettlebell')]"
CSS Selector:
"div>a[href*='28kg-kettlebell']"
Inside Selenium methods it can be as following:
XPath:
driver.find_element(By.XPATH, "//div/a[contains(#href,'28kg-kettlebell')]").click()
CSS Selector:
driver.find_element(By.CSS_SELECTOR, "div>a[href*='28kg-kettlebell']").click()

InvalidSelectorException Error while trying to get text from div class in Selenium Python

I'm trying to get text using Selenium WebDriver and here is my code. Please note that I don't want to use XPath, because in my case the ID gets changed on every relaunch of the web page.
My code:
driver.find_element_by_class_name("05uR6d").text
HTML:
<div class="O5uR6d">to fasten stuff</div>
Error:
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified (Session info: chrome=88.0.4324.150)
Error is specific to the line of code I mentioned above.
How can I fix this?
Use this xpath:
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
Or this CSS:
driver.find_element_by_css_selector(".O5uR6d")
If both won't work, improve your question by adding more data of HTML you are looking at.
It can be done using multiple ways let me try to explain most of them.
Get element by class name.
this is the most easiest solution to get any element by class name you can simply do is:
driver.find_element_by_class_selector('foo');
Get Element by xpath
This is a bit tricky one, you can apply xpath either the class name, title, id or whatever remains same. it also works even if there's a text inside your div. For example:
driver.find_element_by_xpath("//tagname[#attribute='value']")
or in your case:
driver.find_element_by_xpath("//div['class='O5uR6d']")
or you can do something like #vitaliis said
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
You can read more about xpath and how to find it on this link
Get Elements by ID:
You can also get the element from id if there's any that's static:
driver.find_element_by_id('baz')
Get Elements by Name:
Get Elements by name using the following syntax:
driver.find_element_by_name('bazz')
Using CSS Selectors:
You can also use the css selectors to find the elements. Consider a following tag that has some attributes:
<p class="content">Site content goes here.</p>
You can get this element by:
driver.find_element_by_css_selector('p.content')
You can read more about it over here

Send_keys function triggers error message: 'Message: element not interactable'

I'm using Selenium to fill out this HTML form, but when it comes to inputting the data it says 'element not interactable'. I am able to click on the element however actually sending a string produces an error. How can I fix this?
driver.get('https://www.masmovil.es/cobertura-fibra-optica-campos/')
prov = Select(driver.find_element_by_xpath('//*[#id="province"]'))
prov.select_by_index(32)
driver.find_element_by_xpath('//*[#id="town"]').send_keys('1')
Thank you!
In the page you are accessing there are 2 elements that are returned with the selector by_xpath('//*[#id="town"]'), one is a "mm-ui-autocomplete", the other one is an "input".
the "mm-ui-autocomplete" is not visible nor interactable to a real user, that's probably what's throwing the exception you're having, and selenium always takes the first match when there's more than one element returned by the selector, so, assuming you want to type something on the "Localidad" field, it is selecting the wrong element.
Try changing your selector to by_xpath('//input[#id="town"]') and see if it works.
Hope it helps.
Can you try with this css selector :
input[id='town']
code :
driver.find_element_by_css_selector("input[id='town']").send_keys('1')
The xpath (//*[#id="town"]) you have used has two entries :
one with mm-ui-autocomplete tag and one with input tag.
Always give preference to css selector over xpath. It's more stable then xpath.
In case you would not want to use css selector, then you can use xpath like this :
//input[#id='town']
Code :
driver.find_element_by_xpath("//input[#id='town']").send_keys('1')
In my case, it happens that the find_element was not working before the frontend finished loading.
I solved this by adding sleep(2) before the find_element_by_xpath. You will need to import the function by from time import sleep.

how to get unique XPATH for buttons when the features for all input are the same

I am trying to extract NBA players stats using selenium web driver in python and here is my attempt:
from selenium import webdriver
from selenium.webdriver.support.ui import Select
browser = webdriver.Chrome()
browser.get('https://www.basketball-reference.com')
xp_1 = "//select[#id='selector_0' and #name='team_val']"
team = Select(browser.find_element_by_xpath(xp_1))
team.select_by_visible_text('Golden State Warriors')
xp_2 = "//select[#id='selector_0' and #name='1']"
player = Select(browser.find_element_by_xpath(xp_2))
player.select_by_visible_text('Jordan Bell')
The problem I have is there are 4 "Go" buttons in this page and all have the same input features. In other words, the following xpath returns 4 buttons:
//input[#type='submit'and #name="go_button" and #id="go_button" and #value="Go!"]
I unsuccessfully tried adding ancestor as below but it does not return an xpath:
//input[#type='submit' and #name="go_button" and #id="go_button" and #value="Go!"]/ancestor::/form[#id='player_roster']
I appreciate any insight!
Try below XPAth to select required Go button:
"//input[#value='Go!' and ancestor::form[#id='player_roster']]"
or
"//form[#id='player_roster']//input[#value='Go!']"
Note that you shouldn't mix single and double quotes in a XPath expression and correct usage of ancestor axis is
//descendant_node/ancestor::ancestor_node
You could also switch to CSS selectors and use a descendant combination where you use an parent element to restrict to the appropriate form with Go button
#player_roster #go_button
That is
browser.find_element_by_css_selector("#player_roster #go_button")
The # is an id selector.
CSS selectors are generally faster than XPath, except in cases of older IE versions. More info.

How to use selenium to call angular function (ng-click)

I am trying to call a angular ng-click using selenium. This question is based on this javascript:
<span class="col" ng-click="getHope(1,'pray','smile')">100%</span>
This I turned into:
driver.find_element_by_css_selector("[ng-click=getHope(1,'pray','smile')]").click()
I even tried adding span:
driver.find_element_by_css_selector("[ng-click=getHope(1,'pray','smile')]").click()
and adding :
driver.find_element_by_css_selector("span[ng-click=getHope(1,\'pray\',\'smile\')]").click()
But I can the following error:
selenium.common.exceptions.InvalidSelectorException:
Message: invalid selector: An invalid or illegal selector was specified
I tried to mimic this link, but it does not work. What am I doing wrong?
Try the following XPath selector:
driver.find_element_by_xpath("//span[#ng-click=\"getHope(1,'pray','smile')\"]").click()
But a better solution (IMO) would be to execute the function getHope with a JS executor directly.
As per the HTML you have shared to click() on the desired element you can use either of the following Locator Strategies :
xpath :
driver.find_element_by_xpath("//span[#class='col' and contains(.,'100%')]").click()
xpath :
driver.find_element_by_xpath("//span[#class='col' and starts-with(#ng-click,'getHope') and contains(.,'100%')]").click()
css_selector :
driver.find_element_by_css_selector("span.col[ng-click^='getHope']").click()

Categories