Python Selenium: Selecting from a list by text - python

I have spent the past few days trying to solve this problem. I store a string in a variable and i am trying to automate using selenium to select the item whose text()='string stored in the variable'.
I noticed i could not select some of the items in the list even though the text was exactly the same as the string i stored in the variable. The i realized today that some of the texts have a space before the next item. For example;
instead of (Architecture)
it says (Architecture )
This is the code i was running;
fc = 'COMMUNICATION'
faculty = WebDriverWait(driver, 50).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="agentApplicationForm'
'"]/div/div[9]/div['
'1]/div/span/span/span[1]')))
print(faculty.is_displayed())
faculty.click()
sleep(5)
faculty_select = driver.find_element_by_xpath(f'//*[#id="Program1FacultyInstitute_listbox"]/li[text().StartsWith("{fc}")]')
faculty_select.click()
sleep(2)
I am now trying to use text().startsWith({fc}) but i don't think i am using a correct syntax.
This is the error i get;
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression //*[#id="Program1FacultyInstitute_listbox"]/li[text().startsWith("COMMUNICATION")] because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//*[#id="Program1FacultyInstitute_listbox"]/li[text().startsWith("COMMUNICATION")]' is not a valid XPath expression.
(Session info: chrome=88.0.4324.96)
Can someone help me please.
Thank you very much.

Try this to search text starting with:-
//*[#id="Program1FacultyInstitute_listbox"]/li[starts-with(text(),'fc')]
Or maybe try using contains to do substring match like below. But you will need to pass more accurate text to search in order to avoid multiple matches.
//*[#id="Program1FacultyInstitute_listbox"]/li[contains(text(),'fc')]

if you want to select only (one) element based on (text)
you can use
faculty.click()
faculty.send_keys("value you want to select")
notice that this method works only if you want to select only one value based on string , also it works in droplist.

Related

SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//div[#class= ‘encontrados ng-star-inserted’]' is not a valid XPath expression

I am getting syntax error.
My Code:
driver.find_element_by_xpath('//div[#class= ‘encontrados ng-star-inserted’]')
I want to extract the text contained in this site's search result :
Website Link
Your locator is not correct.
Try this instead:
results = driver.find_element_by_css('div.encontrados').text
Or this
results = driver.find_element_by_xpath('//div[contains(#class,"encontrados")]').text
ng-star-inserted is not a fixed class name there while div tag name with encontrados class name are giving fixed unique identification of that element.
Also, your problem is with '//div[#class= ‘encontrados ng-star-inserted’]' xpath expression. You are trying to use ' both for external and the internal string definition while you should use ' for one and " for the other. I.e. or this:
`'//div[#class= "encontrados ng-star-inserted"]'`
or this
`"//div[#class= 'encontrados ng-star-inserted']"`
That's why you are getting the "is not a valid XPath expressing" error since your syntax is not correct too.
So just use one of the expressions I used at the top:
results = driver.find_element_by_css('div.encontrados').text
Or this
results = driver.find_element_by_xpath('//div[contains(#class,"encontrados")]').text
Lucas,
This answer assumes that you want to fetch text out of the website :
print(driver.find_element(By.XPATH, "//html/body").get_attribute('innerHTML'))
I could not find encontrados ng-star-inserted class in the webapp that you have shared.
But if you want to retrieve the text which is in middle of the website, you can do this instead :
for middle_text in driver.find_elements(By.CSS_SELECTOR, "li.resultado-item"):
print(middle_text.text)
driver.find_element_by_xpath('//div[#class= ‘encontrados ng-star-inserted’]')
you have invalid character ‘ enclosing the attribute value use any of:
driver.find_element_by_xpath('//div[#class= "encontrados ng-star-inserted"]')
driver.find_element_by_xpath("//div[#class= 'encontrados ng-star-inserted']")
driver.find_element_by_xpath("//div[#class= \"encontrados ng-star-inserted\"]")
driver.find_element_by_xpath('//div[#class= \'encontrados ng-star-inserted\']')

How can make an Xpath into a loop in python?

I have the following code:
button = driver.find_element_by_xpath("/html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div[1]")
ActionChains(driver).move_to_element(button).click(button).perform()
the next time i wanna click on this button using selenium the x path changes to
button = driver.find_element_by_xpath("/html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div[2]")
ActionChains(driver).move_to_element(button).click(button).perform()
I wanna convert this into a for look in the range(1,5). I used the below code:
l=[1,2,3,4,5]
string=str(l)
for i in string:
button = driver.find_element_by_xpath("/html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div"+i)
ActionChains(driver).move_to_element(button).click(button).perform()
time.sleep(5)
but I am getting the following error:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: Unable to locate an element with the xpath expression /html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div[ because of the following error:
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div[' is not a valid XPath expression.
(Session info: chrome=83.0.4103.61)
Having large xpaths like that are fragile and difficult to navigate. You would probably have more success with a smaller, more accurate xpath.
Addressing your issue:
If you look at your error SyntaxError: Failed to execute 'evaluate' on 'Document': The string '/html/body/div[3]/div/div[1]/div[2]/div[2]/div[2]/div[3]/div[' is not a valid XPath expression.
This is not truncated. This is the xpath you're looking for - You're ending it with an open square bracket so it's not valid.
Have a look at making this xpath string valid before you feed it into find_by.
[edit - URL provided in the comments]
Looking at the page provided, try:
button = driver.find_element_by_xpath("//input[#class='amscroll-load-button']")
ActionChains(driver).move_to_element(button).click(button).perform()
It's a smaller xpath that goes right to the object without navigating the entire DOM.
When I run that xpath it always identifies just 1 object. Even if you click it and the page moves, wherever it moves still it still only identifies one.
If you want to use this, be aware there's an asynchronous page load when you click it. You'll also need a dynamic wait to let the data/page to load before you press it another time.
If you want to just see if it works, the lazy approach is to enter a few seconds of sleep/wait between the click commands.
If you want to know more about finding xpaths using devtools - have a look at this resource. Few videos at 10 minutes each can save a lot of headache on how to get the right objects.

How to do xpath "and" / condition query correctly?

I am trying to set a checkmark on the prime option on amazon.fr.
Here is the link (the prime option is on the left): https://www.amazon.fr/gp/browse.html?node=2036893031.
Here is an image that shows the field I want to checkmark: https://ibb.co/ZY3mK3Z
I have it almost working. But it does not work for all amazon-categories, that's why I added the "and"-operator. Here is my xpath-query:
driver = webdriver.Chrome()
driver.get(category_url)
driver.find_element_by_xpath('//*[#id="leftNav"]/h4[text()="%s"]/following-sibling::ul//input[contains(#name, "s-ref-checkbox-")] and //*[#id="leftNav"]/h4[text()="%s"]/following-sibling::ul//input[contains(#name, "s-ref-checkbox-")]//i[contains(#class, "icon-prime")]' % ("Option d'expédition", "Option d'expédition"))
driver.click()
How can I format my query correctly? Is the and operator even necessary? I get the following error message:
TypeError: Failed to execute 'evaluate' on 'Document': The result is
not a node set, and therefore cannot be converted to the desired type.
I think you are trying to click without passing the WebElement.
You can find the checkbox based on the position of Prime label next to it.
Try the following xpath,
myprime = driver.find_element_by_xpath("//*[contains(#class,'icon-prime a-icon-small s-ref-text-link')]/parent::span/parent::label/input")
myprime.click();
I just tried the XPath below and it uniquely located the element
//label[.//i[contains(#class, 'a-icon-prime')]]/input
^ find a LABEL tag
^ that has a child I tag
^ that contains the class 'a-icon-prime' (indicating the prime logo)
^ then find an INPUT under the LABEL
The minimal working XPath locator would be:
//i[contains(#class,'small') and contains(#class,'prime')]
For better robustness and reliability I would recommend wrapping it into an Explicit Wait like:
prime = WebDriverWait(driver, 10).until(
expected_conditions.presence_of_element_located((By.XPATH, "//i[contains(#class,'small') and contains(#class,'prime')]")))
prime.click()
More information: How to use Selenium to test web applications using AJAX technology

Problems with XPath in Selenium

I want to find element based on it attributes.
I have already tried searching by all divs, and specify by attributes, and even searching by *. None of this was solution.
Whole element looks like this:
<div class="charc" data-lvl="66" data-world="walios" data-nick="mirek">
This is my search expression:
driver.find_element_by_xpath('//div[#data-world="walios"] and [#data-nick="mirek"]')
I would like to find this element using python with selenium, and be able to click on it.
Actually I am getting the error
SyntaxError: Failed to execute 'evaluate' on 'Document': The string '//div[#data-world="walios"] and [#data-nick="mirek"]' is not a valid XPath expression.
What am I doing wrong?
The error message is correct because your predicate(s) is/are not correct.
Try putting the predicate in one [...] expression:
driver.find_element_by_xpath('//div[#data-world="walios" and #data-nick="mirek"]')
driver.find_elements_by_xpath("//div[#data-world="walios" and #data-nick="mirek)]")
or
driver.find_elements_by_xpath("//div[#data-world="walios"][#data-nick="mirek)]")
The multiple conditions for selecting the tag can't be within nested []. Either you have to specify within one [] or within multiple []s.
XPath axes methods:
These XPath axes methods are used to find the complex or dynamic elements. Below we will see some of these methods.
XPath expression select nodes or list of nodes on the basis of attributes like ID , Name, Classname, etc. from the XML document .

xpath to href that contains certain keyword in link itself

What i need is to find all the links on the page that have some keyword inside the link itself. So , based on some stack topics i build my xpath as follows:
response.xpath('//a[contains(#href,'/Best-Sellers-Health-Personal-Care')]')
which should return a link like = "https://www.amazon.com/Best-Sellers-Health-Personal-Care-Tongue......"
But i get Invalid syntax error all the time. What am I mistaken?
So what i do now is just add the if contains check when iterating through the list. But hoped there were more elegant and fast solution.
This is because of inconsistent quotes usage.
Just replace
'//a[contains(#href,'/Best-Sellers-Health-Personal-Care')]'
with
'//a[contains(#href,"/Best-Sellers-Health-Personal-Care")]'

Categories

Resources