how to locate the nested span element locator - selenium

how to locate only parent span which is containing the price value from the below Code,locator strategy doesn't matter:
<div class="price-box price-margin">
<p class="old-price"></p>
<p class="special-price">
<span id="product-price-75254" class="price">
56,90 €
<span class="steuerstern">*</span>
</span>
</p>
</div>

The issue is not the selector here. But the text function.
//p[#class="special-price"]/span[#class="price"]
This will select the node, but selenium will always return the node of the child nodes also. What you are looking for is the node text in this case. This can only be done using JavaScript. Since you didn't mention a language I am going to assume python
elem = driver.find_element_by_xpath('//p[#class="special-price"]/span[#class="price"]')
price = driver.execute_script("return arguments[0].firstChild.textContent.trim();", elem)
print(price)
56,90 €

Using selector you can go like this:
".price-box span.price"
Result:
56,90 €

To test the xpath correctness in Chrome you can use
//span[#class="price"]/text()
Since you didn't mention the language you use , here is an example in nightwatchjs with selenium by using .getText()
.getText() is returning an object, the actual text is the value of callback.
var thetext='';
.getText('//span[#class="price"]' ,fucntion(result){
thetext=result.value();
})

As you haven't mentioned the Selenium bindings you are using so I will construct an Answer through Java bindings. Here we will use a customized xpath to locate the node with text 56,90 € with out the * as follows:
WebElement ele = driver.findElement(By.xpath("//p[#class='special-price']/span[contains(#class,'price') and not(#class='steuerstern')]"));

Related

Choose the correct element from the list of objects with the same className

Quick one, i am trying to avoid using xpath and using css selectors due to performance issues xpath can have so i would like to know the right approach of locating for example "A" in the list
<div class="input-search-suggests" xpath="1">
<div class="input-search-suggests-item">A</div>
<div class="input-search-suggests-item">B</div>
<div class="input-search-suggests-item">C</div>
</div>
Currently i am locating A using xpath / span but it would be indeed sufficient locating all elements and then grabbing A from the list that have same class which is "input-search-suggests-item"
#FindBy(xpath = "//span[contains(text(),'A')]")
CSS_SELECTOR does not have support for direct text what xpath has.
What this means is, for the below xpath
xpath = "//span[contains(text(),'A')]"
based on text A you can not write a css selector.
Instead to locate A using css selector, you can do :
div.input-search-suggests > div.input-search-suggests-item
In Selenium something like this :
#FindBy(cssSelector= "div.input-search-suggests > div.input-search-suggests-item")
Even though it will have 3 matching nodes, but findElement will take the first web element.
Also you may wanna look at nth-child(n)
div.input-search-suggests > nth-child(1)
to make use of index to locate A, B, C
Here is the Reference Link

FInd sibling using XPath

How to find sibling element text using xpath
<label>
<span>some span</span>
</label>
<label>
Second Label
</label>
//label[normalize-space(text()) = 'some span']/following-sibling::label/text()
In Python we would do something like this :
driver.find_element(By.XPATH, "//label[//text()[normalize-space() = 'some span']]/following-sibling::label").text
basically Python Selenium bindings provide a text method for web element. getText() for Java.
Now if you want to heavily dependent on XPATH then you can try below XPATH :
//span[contains(text(),'some span')]/../following-sibling::label
or probably
//span[contains(text(),'some span')]/../following-sibling::label[contains(text(),'Second Label')]
I would use:
//label[span[text()='some span']]/following-sibling::label/text()
or if you only want to find that if it is actually the first following-element:(i.e: you don't want to find that label if there is a input in between)
//label[span[text()='some span']]/following-sibling::*[1][self::label]/text()
or if you only want to find that the first following label(if there even more following label-elements):
//label[span[text()='some span']]/following-sibling::label[1]/text()

Selenium preceding returns a pointer/address and full xpath return a different pointer/address to what I believe should be the same object

Relative Xpath
WebElement precedingClass = driver.findElement(By.xpath("//div[contains(#class, 'pictures')]/preceding::div[contains (#class 'monkey picture') ]"));
Absolute Xpath
WebElment fullXpathAddress = driver.findElement(By.xpath("/html/body/div[6]/div/div[1]/div[1]/div/div[2]/ul/li[20]/div[1]");
HTML Code:
<div class="pictures">
<a ref ....>
<a ref ....>
<h1>x's pictures</h1>
</div>
<div class="animals">
<div class="monkey picture" title="happy monkey"></div>
.
.
</div>
Preceding: Select all nodes that come before the current node.
And you want to select node that is after the current node.
Maybe you can use following as below :
"//div[contains(#class, 'pictures')]/following::div[#class='animals']/div[#class='monkey picture']"
please refer this link to learn more about Xpaths
Please optimize the above Xpath based on your whole DOM structure.
Your Xpath seems wrong
Try below Xpath:
//div[#class='pictures']/following-sibling::a//div[#class='monkey picture']
So the code will be like:
WebElment element = driver.findElement(By.xpath("//div[#class='pictures']/following-sibling::a//div[#class='monkey picture']");
I was able to use preceding::div[x] since I was able to determine index of div "monkey picture" in the list of animals and from the start of animals, the number of divs preceding to "pictures was a fixed value.

Finding Xpath Selenium

I have the following element:
<div class="PickList visible"
widgetid="Palette" id="Palette">
<span class="stuff">
<span class="stuff"><span class="lbl">A-B</span><span class="no">1111</span>
</span>
<span class="stuffSelect"><span class="lblSelect">C</span><span
class="plu">2222</span></span>
The xpath that I am using is:
Driver.driver.findElement(By.xpath("//*[#id="Palette"]//span//span[2]//span[contains(text(),'C')]"));
It's still not able to pickup the letter 'C'.
Any suggestions appreciated. Thanks.
you can try below xpath to track from div.
driver.findElement("//*[#id='Palette']/span[2][#class='stuffSelect']/span[1][contains(text(), 'C')]");
xpath you are using is incorrect. I am providing you with the correct xpath or you can directly fetch it using the className as well.
Updated xpath as per the discussion:
WebElement selectedCharacter = driver.findElement(By.xpath("//div[#id='Palette']//span[#class='lblSelect']"));
selectedCharacter.getText();
By using className:
WebElement selectedCharacter = driver.findElement(By.className("lblSelect"));
selectedCharacter.getText();
Please try the below Xpath.It will print you 'C'
driver.findElement(By.xpath("(//div[#id='Palette']//span[1]//span[2]/span)[1]")).getText()
Here is the xpath. Consider the class visible in your xpath or css. As this denotes that this div might be not visible sometimes. So always be sure to use the visible if you have it as part of the class.
CSS
div.PickList.visible span.lblSelect
xpath
//div[#class='PickList visible']//span[#class='lblSelect']

find specific element for button using selenium for web scraping

I am inspecting one button element from a web page using chrome driver and selenium. And the html code for the particular button is:
<div class="label text-left text-link link-blue text-
uppercase">Financial Statement Analysis <span class="count">(2)</span>
</div>
I have tried different element options like find element by name, xpath, link text etc. But none of them unable to locate the element.
What will be the element to locate the button. ?
try Xpath :
//span[contains(#class,'count') and text() = '(2)']
You can try with this css selector :
div.label.text-left.text-link.link-blue.text-.uppercase
To locate the element with text as Financial Statement Analysis (2) you can use the following solution:
Java Solution:
WebElement elem = driver.findElement(By.xpath("//div[#class='label text-left text-link link-blue text-uppercase'][contains(.,'Financial Statement Analysis')]"));