I'm trying to get the "id" of an html tag, but the xpath doesnt work - xpath

I'm using selenium and i want to get the "id" of an html tag with "find_elements_by_xpath", but i've got this error :
selenium.common.exceptions.InvalidSelectorException: Message: invalid
selector: The result of the xpath expression
"//body[contains(#class,'de')]/div/div[contains(#class,'container-fluid
default')]/section[contains(#id,'mainContent')]/div[contains(#class,'row-fluid')]/div[contains(#id,'contentContainer
row-fluid')]/div[contains(#class,'content')]/div[contains(#class,'ses')]/ul/li/#id"
is: [object Attr]. It should be an element.
When i executed this code:
browser.find_elements_by_xpath("//body[contains(#class,'de')]/div/div[contains(#class,'container-fluid default')]/section[contains(#id,'mainContent')]/div[contains(#class,'row-fluid')]/div[contains(#id,'contentContainer row-fluid')]/div[contains(#class,'content')]/div[contains(#class,'ses')]/ul/li/#id")
While the same code without "/#id" work perfectly but i've got only the text in the "li" tag and it's not what i want.
According to the error, the problem comes from the Xpath.
I expected that this code would return all the "id" that are in "li" html tag, but i got the error.
Thank you for your help

#id is an attribute, not an element. The XPath is OK, but the function only returns elements, not attributes. I doubt there's find_attributes_by_xpath, but if you want to find the li element that has the #id defined, you can specify that in the quantifier:
browser.find_elements_by_xpath("//body[contains(#class,'de')]
/div/div[contains(#class,'container-fluid default')]
/section[contains(#id,'mainContent')]
/div[contains(#class,'row-fluid')]
/div[contains(#id,'contentContainer row-fluid')]
/div[contains(#class,'content')]
/div[contains(#class,'ses')]/ul/li[#id]")
~~~~~
You can then call element.get_attribute('id') to retrieve the id of the element.

Related

Testing text of an element using Cypress

I'd like to validate the text of an element (p element, for instance) with the help of Cypress.
I have used this code:
cy.get('#word').should('have.value', 'Color')
and I received this:
expected <p#word> to have value Color, but the value was ''
Evidently, it validates the CSS but not the html element value. How can I validate the element content here?
If you are asserting the inner Text, instead of have.value you have to use have.text.
cy.get('#word').should('have.text', 'Color')
Or, If you want to assert a partial string, you can use include.text
cy.get('#word').should('include.text', 'Color')

Colly not finding the body tag by xpath but finding it by selector name

I'm learning web scraping using gocolly. When I try to find the tag using selector name body, it successfully finds it. However, when I try to find the body tag by xpath /html/body, it fails to find it.
I have used OnHTML() with a simple callback function:
collector.OnHTML("/html/body", func(element *colly.HTMLElement) {
fmt.Println("Found Body")
})
Any idea as to why is this happening?
Also, when looking at tutorials, I noticed that the selector passed into the function OnHTML() is sometimes wrapped by ""(double quotes) and sometimes by ``(back-ticks). Is there a difference between the two?
How do I search for a ID element because when I'm trying to search for the ID #layout-container under the body, Colly is not finding it:
collector.OnHTML("#layout-container", func(element *colly.HTMLElement) {
fmt.Println("Found Layout Container")
})
Thanks in advance!
From an HTML perspective, the /html part is already implied when using OnHTML.
You would use /html/body, as shown in colly_test.go, with OnXML() (Function will be executed on every XML element matched by the xpath Query parameter)
The test using OnHTML shows only "body".

XPath find_elements_by_xpath() returns empty list, but XPath helper extension shows results

I'm having trouble with getting the href attribute article links from the page with XPath.
So, this is the result from the query using the Chrome extension XPath Helper on https://www.ethics.senate.gov/public/index.cfm/dearcolleagueletters?page=1:
//table[#class="table recordList"]//#href
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from threading import Thread
url_xpath = '//table[#class="table recordList"]//#href'
url = 'https://www.ethics.senate.gov/public/index.cfm/dearcolleagueletters?page=1'
options = Options()
options.headless = True
# change filepath of chromedriver
driver = webdriver.Chrome(options=options, executable_path=r'C:\Users\User\Desktop\chromedriver')
try:
driver.get(url)
print("got url") #<- reaches here
url_elements = driver.find_elements_by_xpath(url_xpath)
print("url_elements", url_elements) # <- doesn't reach here
for url_elements in url_elements:
article_url = url_elements.get_attribute('href')
print("article url", article_url)
except:
pass
Where am I going wrong here?
Thanks
The issue is the xpath expression used.
Because you're using //#href at the end, you're getting an error because the returned results are not actually of type element but an attribute:
Message: invalid selector: The result of the xpath expression "//table[#class="table recordList"]//#href" is: [object Attr]. It should be an element.
Besides this, you're also getting the attachments icon href which may or may not be in your requirements.
To get only the article links you can use this xpath expression:
//table[#class="table recordList"]//a[#class=\'ContentGrid\']
If you need both, the article URL and attachments URL you can use this:
//table[#class="table recordList"]//a[#class='ContentGrid' or #title='View Files']

How to take xpath to Get Text from class inside th

I have the following XPath :
//table[#class='ui-jqgrid-htable']/thead/tr/th//text()
And I'm trying to get the text from it with the following command :
String LabelName = driver.findElement(By.xpath("//table[#class='ui-jqgrid htable']/thead/tr/th//text()")).getText()
But it's not printing text, the result is blank. Could you help me please ?
The text() in your xpath does not qualify as an element. Your element ends at //table[#class='ui-jqgrid-htable']/thead/tr/th. Try using getText() for this XPath.
Also, a table would have many headers. Using findElement will only return the first one.
If you want to get all headers use
driver.findElements(By.xpath("//table[#class='ui-jqgrid-htable']/thead/tr/th"))
and loop through the list to getText of individual element.

Can't compare expected result for <nobr> tag

There is a nobr tag with some text:
<nobr>+380</nobr>
I have described it in page-object:
elements(:txtCode, :nobr, :xpath => "//td[#id='phone_prefix']/nobr")
I need to check its value and I use following expectation:
expect(page.txtCode.text).to eql('+380')
But I'm getting the following error:
undefined method `txtCode' for #<Page:0x3071d30>
How do i describe this nobr element to bring the expect() to work?
You're defining an element collection instead of an element because you're using elements instead of element. The only method that creates on your page object is txtCode_elements. Use element instead.
element(:txtCode, :nobr, :xpath => "//td[#id='phone_prefix']/nobr")
You can read more about element collections from this blog post by Justin Ko: https://jkotests.wordpress.com/2013/06/24/defining-element-collections-using-the-page-objects-gem/

Resources