Using XPath Selector 'following-sibling::text()' in Selenium (Python) - python

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?

#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'.

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 ."

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.

Related

InvalidSelectorException Error while trying to get text from div class in Selenium Python

I'm trying to get text using Selenium WebDriver and here is my code. Please note that I don't want to use XPath, because in my case the ID gets changed on every relaunch of the web page.
My code:
driver.find_element_by_class_name("05uR6d").text
HTML:
<div class="O5uR6d">to fasten stuff</div>
Error:
selenium.common.exceptions.InvalidSelectorException: Message: invalid selector: An invalid or illegal selector was specified (Session info: chrome=88.0.4324.150)
Error is specific to the line of code I mentioned above.
How can I fix this?
Use this xpath:
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
Or this CSS:
driver.find_element_by_css_selector(".O5uR6d")
If both won't work, improve your question by adding more data of HTML you are looking at.
It can be done using multiple ways let me try to explain most of them.
Get element by class name.
this is the most easiest solution to get any element by class name you can simply do is:
driver.find_element_by_class_selector('foo');
Get Element by xpath
This is a bit tricky one, you can apply xpath either the class name, title, id or whatever remains same. it also works even if there's a text inside your div. For example:
driver.find_element_by_xpath("//tagname[#attribute='value']")
or in your case:
driver.find_element_by_xpath("//div['class='O5uR6d']")
or you can do something like #vitaliis said
driver.find_element_by_xpath("//div[contains(text(),'to fasten stuff')]")
You can read more about xpath and how to find it on this link
Get Elements by ID:
You can also get the element from id if there's any that's static:
driver.find_element_by_id('baz')
Get Elements by Name:
Get Elements by name using the following syntax:
driver.find_element_by_name('bazz')
Using CSS Selectors:
You can also use the css selectors to find the elements. Consider a following tag that has some attributes:
<p class="content">Site content goes here.</p>
You can get this element by:
driver.find_element_by_css_selector('p.content')
You can read more about it over here

unable to select an element using xpath in selenium and python

I've been trying to select an element by xpath and display it but I get an error everytime I try to run the code. I got the xpath by doing inspect element and copying full xpath yet it gives me the error. It's a dynamic form too, so I can't choose the direct text and I would probably need to use an address to locate that element as it changes everytime but I've not been able to select that certain element. how do I choose the element?
this is how I tried to choose the element
name_from_doc=browser.find_element_by_xpath('/html/body/form/div[3]/div[3]/div/div[4]/div/div[2]/div[4]/div[2]/text()[1]')
print(name_from_doc)
the error that I get is
InvalidSelectorException: Message: invalid selector: The result of the xpath expression "/html/body/form/div[3]/div[3]/div/div[4]/div/div[2]/div[4]/div[2]/text()[1]" is: [object Text]. It should be an element.
I want to store the name of the person separately and address separately in two different variables
To get the value NAPERVILLE IL Use follwoing xpath to get the element and then use splitlines() and last index value.
name_from_doc=browser.find_element_by_xpath('//div[contains(.,"Billing Address")]/following::div[1]').text
print(name_from_doc.splitlines()[-1])
Update:
name_from_doc=browser.find_element_by_xpath('//div[contains(.,"Billing Address")]/following::div[1]').text
print(name_from_doc.splitlines()[0])
print(name_from_doc.splitlines()[1])
print(name_from_doc.splitlines()[-1])
As the Billing Address text would always be there, so can reach there by using its text in the xpath and then find its exact value by using following in the xpath.
You can do it like:
name_from_doc = browser.find_element_by_xpath("//div[contains(text(),'Billing Address')]//following::div[1]//br[2]")
print(name_from_doc.text)

What is the XPath for the following element?

I need to find the XPath for the following element below:
<a> href="/resident/register/">Register another device </a>
I assumed the solution would be
$x("//*[contains(#href, 'resident/register')]")
But this has returned nothing. Any ideas?
Your HTML is malformed.
Change
<a> href="/resident/register/">Register another device </a>
to
Register another device
then your XPath will work as expected.
If your HTML is fixed, then you'll have to adjust your XPath to test the element content rather than the href attribute content:
//a[contains(.,'resident/register')]
but, although this can select the malformed a element, it won't be clickable since it lacks a proper href attribute.
To start with #kjhughes nailed one of the issue with the HTML i.e. HTML is malformed, as you must have tried to provide a correct HTML from your understanding.
The actual HTML I suppose is as follows:
Register another device
So an effective XPath for the element can be either of the following:
XPath:1
"//a[contains(#href, '/resident/register') and contains(.,'Register another device')]"
XPath:2
"//a[contains(#href, '/resident/register') and normalize-space()='Register another device']"

How to use selenium to call angular function (ng-click)

I am trying to call a angular ng-click using selenium. This question is based on this javascript:
<span class="col" ng-click="getHope(1,'pray','smile')">100%</span>
This I turned into:
driver.find_element_by_css_selector("[ng-click=getHope(1,'pray','smile')]").click()
I even tried adding span:
driver.find_element_by_css_selector("[ng-click=getHope(1,'pray','smile')]").click()
and adding :
driver.find_element_by_css_selector("span[ng-click=getHope(1,\'pray\',\'smile\')]").click()
But I can the following error:
selenium.common.exceptions.InvalidSelectorException:
Message: invalid selector: An invalid or illegal selector was specified
I tried to mimic this link, but it does not work. What am I doing wrong?
Try the following XPath selector:
driver.find_element_by_xpath("//span[#ng-click=\"getHope(1,'pray','smile')\"]").click()
But a better solution (IMO) would be to execute the function getHope with a JS executor directly.
As per the HTML you have shared to click() on the desired element you can use either of the following Locator Strategies :
xpath :
driver.find_element_by_xpath("//span[#class='col' and contains(.,'100%')]").click()
xpath :
driver.find_element_by_xpath("//span[#class='col' and starts-with(#ng-click,'getHope') and contains(.,'100%')]").click()
css_selector :
driver.find_element_by_css_selector("span.col[ng-click^='getHope']").click()

Python selenium test - Facebook code generator XPATH

I'm trying to get the XPATH for Code Generator field form (Facebook) in order to fill it (of course before I need to put a code with "numbers").
In Chrome console when I get the XPATH I get:
//*[#id="approvals_code"]
And then in my test I put:
elem = driver.find_element_by_xpath("//*[#id='approvals_code']")
if elem: elem.send_keys("numbers")
elem.send_keys(Keys.ENTER)
With those I get:
StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
What means wrong field name. Does anyone know how to properly get a XPATH?
This error usually comes if element is not present in the DOM.
Or may be element is in iframe.

Categories