I'm trying to use Selenium (in Python) to extract some information from a website. I've been selecting elements with XPaths but am having trouble using the following-sibling selector. The HTML is as follows:
<span class="metadata">
<strong>Photographer's Name: </strong>
Ansel Adams
</span>
I can select "Photographer's Name" with
In [172]: metaData = driver.find_element_by_class_name('metadata')
In [173]: metaData.find_element_by_xpath('strong').text
Out[173]: u"Photographer's Name:"
I'm trying to select the section of text after the tag ('Ansel Adams' in the example). I assumed I could use the following-sibling selector but I receive the following error:
In [174]: metaData.find_element_by_xpath('strong/following-sibling::text()')
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (328, 0))
... [NOTE: Omitted the traceback for brevity] ...
InvalidSelectiorException: Message: u'The given selector strong/following-sibling::text() is either invalid or does not result in a WebElement. The following error occurred:\n[InvalidSelectorError] The result of the xpath expression "strong/following-sibling::text()" is: [object Text]. It should be an element.'
Any ideas as to why this isn't working?
We can use the concept of following-sibling in xpath for identifying elements in Selenium. It identifies the siblings of the context node. The siblings should be located at the equal level of the existing node and should have the same parent.
XPath text() function is a built-in function of the Selenium web driver that locates items based on their text. It aids in the identification of certain text elements as well as the location of those components within a set of text nodes. The elements that need to be found should be in string format.
We can find a next sibling element from the same parent in Selenium webdriver. This is achieved with the help of xpath locator. It is important to note that it is only possible to traverse from current sibling to the next sibling with the help of xpath.
The major difference between the following and following siblings is that the following sibling takes all the sibling nodes after the context but will also share the same parent.
@RossPatterson is correct. The trouble is that the text 'Ansel Adams' is not a WebElement
, so you cannot use find_element
or find_elements
. If you change your HTML to
<span class="metadata">
<strong>Photographer's Name: </strong>
<strong>Ansel Adams</strong>
</span>
then find_element_by_xpath('strong/following-sibling::*[1]').text
returns 'Ansel Adams'.
To get the text "Ansel Adams", just use metaData.get_text()
. I don't believe find_element_by_*
will allow you to find a text node.
This is documented in this Selenium bug report: http://code.google.com/p/selenium/issues/detail?id=5459
"Your xpath doesn't return an element; it returns a text node. While this might have been perfectly acceptable in Selenium RC (and by extension, Selenium IDE), the methods on the WebDriver WebElement interface require an element object, not just any DOM node object. WebDriver is working as intended. To fix the issue, you'd need to change the HTML markup to wrap the text node inside an element, like a ."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With