Find locator with contains text (Robotframework) - xpath

From this code as below:
<span id="cTDQo7-img" class="z-menu-img"></span> payment
<span id="cTDQo7-img" class="z-menu-img"></span>
"payment"
I would like to get locator use keyword contains but the word "payment" is
a lot of the page such as payment1,payment2,payment3
And id is not unique.
I tried to use the code below but not work for me.
//a[contains(.,'payment')]
//span[#class='z-menu-img'] [contains(.,'payment')]
//span[#class='z-menu-img'] and [contains(.,'payment')]
//span[#class='z-menu-img'] contains(.,'payment')

Option 1 : Use the other attributes in combination with text
//a[#class='z-menu-cnt z-menu-cnt-img' and normalize-space(.)='payment']
Option 2: Specify the position if you have multiple elements without unique attributes/path
(//a[contains(.,'payment')])[1]
The second xpath will identify the first occurrence of the link contains text 'payment'. You can change the tagname and index based on your interest.

Related

Xpath get element above

suppose I have this structure:
<div class="a" attribute="foo">
<div class="b">
<span>Text Example</span>
</div>
</div>
In xpath, I would like to retrieve the value of the attribute "attribute" given I have the text inside: Text Example
If I use this xpath:
.//*[#class='a']//*[text()='Text Example']
It returns the element span, but I need the div.a, because I need to get the value of the attribute through Selenium WebDriver
Hey there are lot of ways by which you can figure it out.
So lets say Text Example is given, you can identify it using this text:-
//span[text()='Text Example']/../.. --> If you know its 2 level up
OR
//span[text()='Text Example']/ancestor::div[#class='a'] --> If you don't know how many level up this `div` is
Above 2 xpaths can be used if you only want to identify the element using Text Example, if you don't want to iterate through this text. There are simple ways to identify it directly:-
//div[#class='a']
From your question itself you have mentioned the answer for it
but I need the div.a,
try this
driver.findElement(By.cssSelector("div.a")).getAttribute("attribute");
use cssSelector for best result.
or else try the following xpath
//div[contains(#class, 'a')]
If you want attribute of div.a with it's descendant span which contains text something, try as below :-
driver.findElement(By.xpath("//div[#class = 'a' and descendant::span[text() = 'Text Example']]")).getAttribute("attribute");
Hope it helps..:)

XPath - Nested path scraping

I'm trying to perform html scrapping of a webpage. I like to fetch the three alternate text (alt - highlighted) from the three "img" elements.
I'm using the following code extract the whole "img" element of slide-1.
from lxml import html
import requests
page = requests.get('sample.html')
tree = html.fromstring(page.content)
text_val = tree.xpath('//a[class="cover-wrapper"][id = "slide-1"]/text()')
print text_val
I'm not getting the alternate text values displayed. But it is an empty list.
HTML Script used:
This is one possible XPath :
//div[#id='slide-1']/a[#class='cover-wrapper']/img/#alt
Explanation :
//div[#id='slide-1'] : This part find the target <div> element by comparing the id attribute value. Notice the use #attribute_name syntax to reference attribute in XPath. Missing the # symbol would change the XPath selector meaning to be referencing a -child- element with the same name, instead of an attribute.
/a[#class='cover-wrapper'] : from each <div> element found by the previous bit of the XPath, find child element <a> that has class attribute value equals 'cover-wrapper'
/img/#alt : then from each of such <a> elements, find child element <img> and return its alt attribute
You might want to change the id filter to be starts-with(#id,'slide-') if you meant to return the all 3 alt attributes in the screenshot.
Try this:
//a[#class="cover-wrapper"]/img/#alt
So, I am first selecting the node having a tag and class as cover-wrapper and then I select the node img and then the attribute alt of img.
To find the whole image element :
//a[#class="cover-wrapper"]
I think you want:
//div[#class="showcase-wrapper"][#id="slide-1"]/a/img/#alt

What XPATH I need to extract the text inside SPAN that is preceded by a specific label inside a STRONG, both inside a P?

What XPATH I need to extract the text inside SPAN that is preceded by a specific label inside a STRONG, both inside a P?
For example to extract website and email addresses from a page that looks like this:
<p>
<strong>Website:</strong>
<span>www.example.com</span>
</p>
<p>
<strong>Contact email:</strong>
<span>email#example.com</span>
</p>
This shall do:
//p/span[preceding::*[1][self::strong and . = 'Contact email:']]
Here, you are selecting all p/span elements with first preceding element strong, where label is Contact email:
Website:
//p/span[preceding::strong[1]/text()='Website:']
Email:
//p/span[preceding::strong[1]/text()='Contact email:']
It is also important to note that, by using preceding axes as shown in the other two answers, the XPath will mistakenly return span element that is formed like the following :
<strong>Website:</strong>
<p>
<span>www.example.com</span>
</p>
You can use preceding-sibling axes instead to avoid the mistake mentioned above :
//p/span[preceding-sibling::*[1][self::strong and . = 'Website:']]
preceding-sibling axes only consider elements that is located before context element (the span in this case), and is sibling (share the same parent) of the context element.

XPath exclude given class

I'm trying to extract text from a div but excluding a given class:
This is what i'm trying:
$pattern = "//div/#title[not(contains (#class, 'second_card local_impact_icon impact-2'))]";
but its not excluding the given class, i need to extract just the text of title='' but just from the first div title.
This is the html:
<div class="match_info"><div title='Yellow Card' class='local_impact_icon impact-1'></div><div title='Red Card' class='second_card local_impact_icon impact-2'></div></div>
Following XPath
//div/div[not(contains (#class, 'second_card local_impact_icon impact-2'))]/#title
returns
title="Yellow Card"
Simplified explanation - just select the div that doesn't contain the class you want to exclude and retrieve the title attribute for this div only. When you set this exclude at the position ../#title you already are at the title-attributes of both divs.
And as the question is how to retrieve the text - in given example
string(//div/div[not(contains (#class, 'second_card local_impact_icon impact-2'))]/#title)
returns Yellow Card

Xpath: match a node only if one sub-node contains special string

First sample:
<ul class="breadcrumbs">
<li>Home</li>
<li>Movies</li>
<li>Thrilling Action</li>
<li><strong>Armageddon</strong></li>
</ul>
Second sample:
<ul class="breadcrumbs">
<li>Home</li>
<li>Food</li>
<li>Sweet rice</li>
<li><strong>Uncle Ben's Boil-In-Bag Rice</strong></li>
</ul>
This is how far I have come:
/html/body//ul[#class='breadcrumbs']/li[2]/a[contains(., 'Movies') or contains(., 'Cool Gadgets')]
Extracts Movies - but I also want it to extract Thrilling Action.
Explained: If the <a>-tag of second <li>-tag contains the strings "Movies" or "Cool Gadgets" I want to extract the <a>-tags of the second and the third <li>-tag.
/html//ul[#class='breadcrumbs']/li[2]/a
/html//ul[#class='breadcrumbs']/li[3]/a
If li[2] dosen't contain "Movies" or "Cool Gadgets", I don't want to extract anything!
If I get it right, you want to match all the <li> tags inside an <ul> if one of the <li> contains a special string. You could use:
//ul[#class="breadcrumbs" and (li[2]/a/text() = "Movies" or li[2]/a/text() = "Cool Gadgets")]/li[position() > 1]/a/text()
Explanation
1) The first part, //ul[#class="breadcrumbs" and (li[2]/a/text() = "Movies" or li[2]/a/text() = "Cool Gadgets")], will check you're in a <ul> tag that fits your needs.
#class="breadcrumbs" does what you might expect, and li[2]/a/text() = "Movies" or li[2]/a/text() = "Cool Gadgets" will return true if your filtering string is present.
Of course, if needed, you can change a/text() = "Movies" into a[contains(text(), "Movies")].
2) Once we know we're in the right place, all we have to do is select the fields you want. This is done by li[position() > 1] which will catch every <li> except the first. Select the text, and you're good to go!
The Document Type Declaration (see DocumentType) associated with this document.
For XML documents without a document type declaration this returns null.
For HTML documents, a DocumentType object may be returned, independently of the presence or absence of document type declaration in the HTML document.
This provides direct access to the DocumentType node, child node of this Document. This node can be set at document creation time and later changed through the use of child nodes manipulation methods, such as Node.insertBefore, or Node.replaceChild.
Note, however, that while some implementations may instantiate different types of Document objects supporting additional features than the "Core", such as "HTML" [DOM Level 2 HTML] , based on the DocumentType specified at creation time, changing it afterwards is very unlikely to result in a change of the features supported.
coolgadgets

Resources