Finding xpath of element - html

In the following snippet
I want to get xpath of the element containing the text 'This is what I should get'. I use the xpath expression html/body/div[5]/div[3]/div/div/div/div[2]/div/table/tbody/tr[2]/td/span, but I am getting the element with text 'This is what I am getting'. Please help me to modify element locator to get desired text

There must be a better XPath expression than that verbose one, but without more information I can only suggest based on the existing XPath. So, the desired text node can be identified either as text node that follows the previously selected span element :
..../table/tbody/tr[2]/td/span/following-sibling::text()[1]
or as direct child text node from the parent td element :
..../table/tbody/tr[2]/td/text()[normalize-space()]

If you want to get the text node, the xpath would be:
html/body/div[5]/div[3]/div/div/div/div[2]/div/table/tbody/tr[2]/td/text()[2]
Although xPath expression should probably less verbose.

Related

XPath - get text from whole document except text from specified elements

I'm trying to figure out how to get text using XPath and exclude some tags.
Let's say (for illustration) I want to get all text from this page's body tag (so all visible text), but I don't want my text to contain text from tags with class="comment-copy" i.e. I don't want text to include comments.
I tried this but it doesn't work. It returns text including comments.
//body//text()[not(*[contains(#class,"comment-copy")])]
Do you have any idea?
EDIT:
Probably figured it out but maybe there are better or faster approaches so I won't delete the question.
//body//text()[not(ancestor-or-self::*[contains(#class,"comment-copy")])]
You were very close.
Just change
//body//text()[not(*[contains(#class,"comment-copy")])]
to
//body//text()[not(contains(../#class,"comment-copy"))]
Note that this will only exclude immediate children text() nodes of comment-copy marked elements. Your follow-up XPath will exclude all descendant text() nodes beneath comment-copy marked elements.
Note: You might want to beef up the robustness of the #class test; see Xpath: Find element with class that contains spaces.

writing xpath for getting a row in a table

If I write the XPath for a row in a table which is expandable, like each row is expandable on the table. it has a dropdown. if I click on the dropdown of the row, I get to see some stuff inside it.
if I want to write XPath for the body inside the dropdown. ex: for the second row, I get it by writing the XPath:
//div[#class=‘react-bs-container-body’]//tbody/tr[2]
If i write the following xpath :
//div[#class=‘react-bs-container-body’]//tbody/tr[td[#tabindex="7"]]
where I am trying to access the same thing by giving the attribute of the column which is unique. Xpath should give me the body inside the dropdown.
but this is not happening. The second case won't work. Can anyone tell me why?
You can try this xpath with single quotations,
//div[#class=‘react-bs-container-body’]//tbody/tr[td[#tabindex='7']]
Also, you can try with the below xpath as well
//div[#class=‘react-bs-container-body’]//tbody/tr[td[7]]

Xpath selecting nodes with text

I have 2 requests.
First i need xpath expression that selects all <tr> elements with any kind of text nested in that element.
I tried with :
//tr[contains(., 'PRVI ODJELJAK')]/following-sibling::tr[text() != '']
but it doesnt work it still selects siblings w/o a text also. :/
secondly is there a way to lets say select all siblings of an element until you hit a sibling with inner text matching some text.
Thx in advance!
"First i need xpath expression that selects all elements with any kind of text nested in that element"
To filter element that contains some non-whitespace text in it, you can use normalize-space() :
//tr[contains(., 'PRVI ODJELJAK')]/following-sibling::tr[normalize-space()]
"secondly is there a way to lets say select all siblings of an element until you hit a sibling with inner text matching some text"
Probably you can emulate that by selecting siblings where there is following-sibling with inner text matching some text
following-sibling::tr[following-sibling::tr[contains(.,'some text')]]

Get (text) in XPath

I have the following DOM structure / HTML, I want to get (just practicing...) the marked data.
The one that is under the h2 element. that div[#class="coordsAgence"] element, has some more div children below and some more h2's.. so doing:
div[#class="coordsAgence"]
Will get that value, but with additional unneeded text.
UPDATE: The value (From this example) that I basically want is that: "GALLIER Dennis" text.
It seems you want the first text node in that div:
div[#class="coordsAgence"]/text()[1]
should do it.
Note that this assumes that there is actually no whitespace between those comments inside <div class="coordsAgence">; otherwise that whitespace will constitute additional text nodes that you'll have to account for.
Get the first text node following the first h2 in the div with class "coordsAgence":
div[#class='coordsAgence']/h2[1]/following-sibling::text()[1]
Note that this first expression returns the first text node after the first h2 even when some other node appears between the two. If you want to return the text only when it's the node that immediately follows the first h2, then try something like this:
div[#class='coordsAgence']/h2[1][following-sibling::node()[1][self::text()]]/following-sibling::text()[1]
using Python/Scrapy to get text from h1 tag(for example):
response.xpath(
"//div[contains(#class, 'class_name')]//h1[contains(#class, 'class_name')]/text()"
).get()

xpath help can't get the text?

I am unable to get the text from this website: http://mp3bear.com...so now I just want to get the title of the song that is displayed on it.. here is what i wrote as the code:
//table/tr[2]/td[2]
so now I want to get second row from second column... it doesn't display anything.... is there any thing special when
I can't find any table element on this site, the tables are constructed with divs.
Therefore the expression for the second row of the second column of the table is.
//div[#id='listwrap']/div[3]/div[2]
There are some xpath implementations that don't allow indexing of child elements in this manner. In this case you could use
//div[#id='listwrap']/div[position()='3']/div[position()='2']
Edit:
In that case you need this expression:
//div[#id='listwrap']/div[3]/div[2]/a/text()
as the title is contained in a 'a' element and you use the xpath function text() to get the text value of the 'a' element
tested in firepath.