Problems with XPath in Selenium - python

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 .

Related

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")]'

Robot Framework - check if element defined by xpath exists

I'm wondering, I'd love to find or write condition to check if some element exists. If it does than I want to execute body of IF condition. If it doesn't exist than to execute body of ELSE.
Is there some condition like this or is it necessary to write by myself somehow?
By locating the element using xpath, I assume that you're using Sselenium2Library. In that lib there is a keyword named:
Page Should Contain Element which requires an argument, which is a selector, for example the xpath that defines your element.
The keyword failes, if the page does not contain the specified element.
For the condition, use this:
${Result}= Page Should Contain Element ${Xpath}
Run Keyword Unless '${RESULT}'=='PASS' Keyword args*
You can also use an other keyword: Xpath Should Match X Times
I prefer using Get Matching XPath Count since the accepted answer throws error if element is not found
${count}= Get Matching XPath Count ${Xpath}
Run Keyword And Return If ${count} > 0 Keyword args*
I also had the same doubt, but above answers doesn't satisfy what I wanted to
so,I used rpaframework library
*** Settings ***
Library RPA.Browser.Selenium
*** Tasks ***
Verifying if a link is present or not
Open Available Browser https://www.amazon.com
${val} Does Page Contain Link //a[contains(#href,'some_text_present_in_your_link')]
IF ${val}== True
Log Link is present in the web page.
ELSE
Log Link is not present in the web page.
There are many keywords present in this library to verify other things like elements, button, checkbox, image, textfield etc.
These keywords return True or False, so we can perform other steps based on variable value.
Note: Do not forget to install the rpaframework library.
pip install rpaframework

Extract text between tags with XPath including markup

I have the following piece of XML:
...<span class="st">In Tim <em>Power</em>: Politieman...</span>...
I want to extract the part between the <span> tags.
For this I use XPath:
/span[#class="st"]
This however will extract everything including the <span>.
and.
/span[#class="st"]/text()
will return a list of two text elements. One containing "In Tim". The other ":Politieman". The <em>..</em> is not included and is handled like a separator.
Is there a pure XPath solution which returns:
In Tim <em>Power</em>: Politieman...
EDIT
Thanks to #helderdarocha and #TextGeek. Seems non trivial to extract plain text with XPath only including the <em>.
The /span[#class="st"]/node() solution creates a list containing the individual lines, from which it is trivial in Python to create a String.
To get any child node you can use:
/span[#class="st"]/node()
This will return:
Two child text nodes
The full <em> node (element and contents).
If you actually want all the text() nodes, including the ones inside em, then get all the text() descendants:
/span[#class="st"]//text()
or
/span[#class="st"]/descendant::text()
This will return three text nodes, the text inside <em>, but not the <em> elements.
Sounds like you want the equivalent of the Javascript DOM innerHTML() function, but for XML. I don't think there's a way to do that in pure XPath.
XPath doesn't really operate on markup strings like "<em>" and "</em>" at all -- it works with a tree of Node objects (there might possibly be an XPath implementation that tries to work directly off markup, but I doubt it). Most XPath implementations wouldn't even have the 4 characters "<em>" anywhere (except maybe kept around for printing error messages or something), and of course the DOM could have been built from scratch rather than from XML or other input in the first place. Likewise, XPath doesn't really figure on handing back marked-up strings, but lists of nodes.
In XSLT or XQuery you can do this easily, but not in XPath by itself, unless I'm missing something.
-s

Iterate through multiple class using find_element_by_class_name in Selenium

I am using Selenium webdriver in Python for a web-scraping project.
The webpage, I am working on has a number of Table entries with the same class name.
<table class="table1 text print">
I am using find_element_by_class_name. However I am getting a error :
*Compound class names not permitted *
Another question:
How to iterate through all the tables having the same css classname ?
Thanks
You should use find_elements_by_class_name. This will return an iterable object.
The error you describe happens when you provide multiple class names rather than a single one. An easy way around this is to get the elements using CSSSelector or XPath. Alternatively, you could use find_elements_by_class_name and provide one class name, then iterate through that list to find the elements that match the additional class names you want to match on as well.

Selenium-rc Python client : Not able to iterate through the xpath?

I am a newbie to Selenium and is implementing selenium-rc with Python client library. I tried traversing through my page's div using xpath(s) elements using the command "sel.get_xpath_count(xpath)".
It gives a count of 20, but when I iterate through every div using for statement and command "sel.get_text(xpath='%s[%d]'%(xpath, i))", but it only finds the first element and give a error on the remaining 19 saying divs not found.
Your second XPath expression is wrong. Programmers trained in C-style languages frequently make this mistake, because they see [...] and think "index into an array", but that's not what brackets do in XPath.
If you use sel.get_xpath_count(something), then you need to use sel.get_text("xpath=(something)[item_number]"). Note the use of parentheses around the original XPath expression in the second use.
The reason behind this is that something[item_count] is short-hand for something AND position() = item_count - thus you wind up adding another predicate to the "something" expression, instead of selecting one of the nodes selected by the expression. (something)[item_count] works because the value of (something) is a list of nodes, and adding a position() = item_count selects the node from the list with the specified position. That's more like a C-style array.

Categories

Resources