I am trying to get text from child node from the element tree but when i try to get specific element it is getting empty array.
Here is my command in Chrome Console : $x('//*[#id="mainform"]/child::text()[10]')
then I need to get textContent value which is Memorable word and I dont know how to get it.
Any suggestion appreciated.
you are getting a list of elements, you just need to visit the one you need:
$x('//*[#id="mainform"]/child::text()[10]')[0]
Related
I am trying to write an XPath expression which can return the URL associated with the next page of a search.
The URL which leads to the next page of the search is always the href in the a tag following the tag span class="navCurrentPage" I have been trying to use a following-sibling term to pull the next URL. My search in the Chrome console is:
$x('//span[#class="navCurrentPage"][1]/following-sibling::a/#href[1]')
I thought by specifying #href[1] I would only get back one URL (thinking the [1] chooses the first element in list), but instead Chrome (and Scrapy) are returning four URLs. I don't understand why. Please help me to understand how to select the one URL that I am looking for.
Here is the URL where you can find the HTML giving me trouble:
https://www.yachtworld.com/core/listing/cache/searchResults.jsp?cit=true&slim=quick&ybw=&sm=3&searchtype=advancedsearch&Ntk=boatsEN&Ntt=&is=false&man=&hmid=102&ftid=101&enid=0&type=%28Sail%29&fromLength=35&toLength=50&fromYear=1985&toYear=2010&fromPrice=&toPrice=&luom=126¤cyid=100&city=&rid=100&rid=101&rid=104&rid=105&rid=107&rid=108&rid=112&rid=114&rid=115&rid=116&rid=128&rid=130&rid=153&pbsint=&boatsAddedSelected=-1
Thank you for the help.
Operator precedence: //x[1] means /descendant-or-self::node()/child::x[1] which finds every descendant x that is the first child of its parent. You want (//x)[1] which finds the first node among all the descendants named x.
xpath index will apply on all matching records, if you want to get only the first item, get the first instance.
$x('//span[#class="navCurrentPage"][1]/following-sibling::a/#href[1]').extract_first()
just add, .extract_first() or .get() to fetch the first item.
see the scrapy documentation here.
I've found this very helpful to make sure you have the bracket in the right place.
What is the XPath expression to find only the first occurrence?
also, the first occurrence may be [0] not [1]
I am trying to locate Ajax control (mouse over) on Amazon home page for sign in.
WebElement element = driver.findElement(By.xpath("//*[#id='nav-link-yourAccount']"));
however this element locator works for some time and other times its not finding element and script is failing.
I have noticed that Xpath of this element is changing sometimes to //*[#id='nav-link-yourAccount']/span[1], there is no any other unique identifier which can be used to locate this element.
Could you please let me know how to resolve this variable xpath issue.
If you fail to find an element at one of the xpath values, you could try searching for the other xpath value. You could use ExpectedConditions to wait for a certain period of time for an element to exist. If that time elapses and the element is not found, then use the second locator to find the element. This assumes that the xpath is only changing between these two known values. Also, once you locate the element, you might want to make some assertions about the other properties of the element to further ensure you've found the element you're looking for.
Here's a post about waiting for an element:
Equivalent of waitForVisible/waitForElementPresent in Selenium WebDriver tests using Java?
I am trying to get these two attributes separately. When I try to get the version class the duration also gets lumped in with it as the tag is not closed. Also if there happens to be no version then I'd just get the duration returned. How do I ensure I grab this data separately and correctly?
Here's the html:
<span class="version">Original Version <span class="duration">(6:20)</span></span>
This is my current code and also the results I get now:
.//span[#class='duration'] Result: "(6:20)" CORRECT
.//span[#class='version'] Result: "Original Version (6:20)" INCORRECT!
I tried playing around with the 'not contains' operator but still cannot figure it out. Thanks for any help in advance.
This might be one of the few valid use cases for text():
.//span[#class='version']/text()
would give you just text nodes that are direct children of the version span, and not the text contained in any child elements.
In your example you'd get one text node whose value is "Original Version " (including a trailing space).
I am trying to find XPath of an element which has no attribute. It can only be identified by its parent's attribute. However, the parent also does not have unique attribute.
Eg: //*[#id="btn"][1]/ul/li[2]/a/span
Here there are 2 elements with id=btn. How do i get the 2nd element. The above syntax gives me 1st element.. However if i use:
//*[#id="btn"][2]/ul/li[2]/a/span
I get an error message
"The xpath expression '//*[#id="btn"][2]/ul/li[2]/a/span' cannot be evaluated or does not result in a WebElement "
Try this, you select those two first, then use brackets around and index them.
(//*[#id="btn"]/ul/li[2]/a/span)[2]
By the way, it's not a good practice to have multiple elements sharing same ids, if you are the developer, may consider change them.
I have tried refraining from asking for help, but I have had enough! I am trying to get the child elements of a node; all except one with a particular id. This is what I have thus far:
//*[#id='a']/*[#id!='b']
It works to some extent. It gets all child elements of 'a' that do not have an id of 'b', but I want it to get all child elements, regardless whether it has an id attribute or not.
Any ideas?
Try using not(), eg
//*[#id="a"]/*[not(#id="b")]