I am unable to locate first span with XPath I tried:
//*[#id='student-grid']/div[2]/div[1]/table/tbody/tr[1]/td/span/span[contains(text(), 'Edit School')]
to select span with text - Edit Student button
<tbody role="rowgroup">
<tr class="" data-uid="2f3646c6-213a-4e91-99f9-0fbaa5f7755d" role="row" aria-selected="false">
<td class="select-row" role="gridcell">
<td class="font-md" role="gridcell">marker, Lion</td>
<td role="gridcell">TESTLINK_1_ArchScenario</td>
<td role="gridcell">1st</td>
<td role="gridcell">Not Started</td>
<td role="gridcell"/>
<td role="gridcell"/>
<td role="gridcell">QA Automation TestLink Folders</td>
<td class="k-cell-action" role="gridcell"/>
<td class="k-cell-action detail-view-link font-md" role="gridcell">
<span class="button-grid-action kendo-lexia-tooltip icon-pencil" role="button" title="Edit Student">
<span>Edit Student</span>
</span>
</td>
<td class="k-cell-action archive-link font-md" role="gridcell">
<span class="button-grid-action kendo-lexia-tooltip icon-archive" role="button" title="Archive Student">
<span>Archive Student</span>
</span>
</td>
</tr>
</tbody>
If you want to select span with text - Edit Studen try any of this:
//span[#title='Edit Student']/span
//span[text()='Edit Student']
If you want to select Edit Studen with role="button" try any of this:
//span[#title='Edit Student'][#role='button']
//span[#role='button'][./span[text()='Edit Student']]
//span[#role='button'][./span[.='Edit Student']]
simply use can use any of this xpaths
//span[contains(text(),'Edit Student')]
//*[contains(text(),'Edit Student')]
//span [#class='button-grid-action kendo-lexia-tooltip icon-pencil']/span
//span [#title='Edit Student']/span
//span [contains(#title,'Edit Student')]/span
//span [contains(#class,'button-grid-action kendo-lexia-tooltip icon-pencil')]/span
To select the outer span, this XPath,
//span[#role='button' and normalize-space()='Edit School']
will select span elements with a button #role and a normalized string value of Edit School.
To select the inner span, this XPath,
//span[text()='Edit School']
will select span elements with an immediate text node child whose value is Edit School.
You can, of course, further qualify the heritage in either case as needed.
See also
Testing text() nodes vs string values in XPath
This should get the span text
//span[.='Edit Student']
Related
I'm trying to display a button for each even row in my table ( Thymeleaf ) but I'm not sure how can I do it
<tr th:each="item, iter : ${flightlist}">
<td th:text="${item.flightNumber}"></td>
<td th:text="${item.airline}"></td>
<td th:text="${item.origin}"></td>
<td th:text="${item.destination}"></td>
<td th:text="${#dates.format(item.takeOffDate, 'MM-dd-yyyy')}"></td>
<td th:text="${item.takeOffTime}"></td>
<td th:text="${#dates.format(item.landingDate, 'MM-dd-yyyy')}"></td>
<td th:text="${item.landingTime}"></td>
<td th:text="${item.flightDuration}"></td>
<td th:text="${item.price}"></td>
// Display button code here if true for even
<td th:if="${iter.even == true ? '<a type="button" class="btn btn-primary"
href="/addUserFlight?id=${item.flightNumber}">Select</a> ' : ''}"></td>
</tr>
Edit: Iter worked!
You can use the Thymeleaf iterStat convention to get the value of even:
<tr th:each="item, iterStat : ${flightlist}">
<td th:text="${item.flightNumber}">[flight number]</td>
<td th:text="${item.airline}">[airline]</td>
<td th:text="${item.origin}">[origin]</td>
<td th:text="${item.destination}">[destination]</td>
<td th:text="${#dates.format(item.takeOffDate, 'MM-dd-yyyy')}">[takeOffDate]</td>
<td th:text="${item.takeOffTime}">[takeOffTime]</td>
<td th:text="${#dates.format(item.landingDate, 'MM-dd-yyyy')}">[takeOffTime]</td>
<td th:text="${item.landingTime}">[landingTime]</td>
<td th:text="${item.flightDuration}">[flight duration]</td>
<td th:text="${item.price}">[price]</td>
<td><a th:if="${iterStat.even}"
type="button"
class="btn btn-primary"
th:href="#{/addUserFlight(id=${item.flightNumber})}">Select</a></td>
</tr>
Note that you also want to put this th:if in your <a> tag because the column will otherwise not be included and it will break the design of your table.
You'll want to review the syntax for anchor tags too. You would need th: on the href because you will want Thymeleaf to dynamically evaluate your flight numbers.
Take a look at #numbers.formatCurrency() to format your price
You can include th:if=${!#lists.isEmpty(flightlist)} on the <table> to not show the table if there are no flights.
Lastly, include some default values between tags so that if you open up the page on a browser without a container, you can still what the design will look like. I usually just include the name of the property.
I`m using Scrapy Python to try to grep data from the site.
How I can grep this structure with Xpath?
<div class="foo">
<h3>Need this text_1</h3>
<table class="thesamename">
<tbody>
<tr>
<td class="tmp_year">
45767
</td>
<td class="tmp_outcome">
<b>Win_1</b><br>
<span class="tmp_category">TEST_1</span>
</td>
</tr>
<tr>
<td class="tmp_year">
1232004
</td>
<td class="tmp_outcome">
<b>Win_2</b><br>
<span class="tmp_category">TEST_2</span>
</td>
</tr>
<tr>
<td class="tmp_year">
122004
</td>
<td class="tmp_outcome">
<b>Win_3</b><br>
<span class="tmp_category">TEST_3</span>
</td>
</tr>
</tbody>
<h3>Need this text_2</h3>
<table class="thesamename">
<tbody>
<td class="tmp_year">
234
</td>
<td class="tmp_outcome">
<b>Win_E</b><br>
<span class="tmp_category">TEST_E</span>
</td>
</tr>
<tr>
<td class="tmp_year">
3476
</td>
<td class="tmp_outcome">
<b>Win_C</b><br>
<span class="tmp_category">TEST_C</span>
</td>
</tr>
</tbody>
<h3>Need this text_3</h3>
<table class="thesamename">
<tbody>
<tr>
<td class="tmp_year">
85567
</td>
<td class="tmp_outcome">
<b>Win_T</b><br>
<span class="tmp_category">TEST_T</span>
</td>
</tr>
<tr>
<td class="tmp_year">
435656
</td>
<td class="tmp_outcome">
<b>Win_A</b><br>
<span class="tmp_category">TEST_A</span>
</td>
</tr>
<tr>
<td class="tmp_year">
980
</td>
<td class="tmp_outcome">
<b>Win_Z</b><br>
<span class="tmp_category">TEST_Z</span>
</td>
</tr>
</tbody>
I would like to have output with this structure:
"Section": {
Need this text_1 :
[45767 : Win_1 : TEST_1]
[1232004 : Win_2 : TEST_2]
[122004: Win_3 : TEST_3]
,
Need this text_2:
[234 : Win_E : TEST_E]
[3476 : Win_C : TEST_C]
,
Need this text_3:
[85567 : Win_T : TEST_T]
[435656 : Win_A : TEST_A]
[980: Win_Z : TEST_Z]
}
How can I create the proper xpath select to take this structure?
I can take separately all "h3" , all "a" then all tags with class but how I can match?
GREP YOU SAY?! LOL Well, You would be entirely wron to name it so but for the sake ofkeeping the jargon cleanfor understanding your just parsing/extracting.... So new to scrapy? or web dev sideof things? No matter... Theres no way I couldexpect to teach you in one answer here how to xpth/regex like a pro... only wayis for you to keep at but I throw in my input.
First of all, xpath is amazingly usefull wen it comes to websites that are necessarily build to stadard, which doesnt make them bad per say but in the html snipet you gave... its structured all right soo.. Id recommend css extract .. THESE ARE THE VALUES...
year = response.css('td.tmp_year a::text').extract()
outcome = response.css('td.tmp_outcome b::text').extract()
category= response.css('span.tmp_category::text').extract()
PRO-TIP: For what ever case you deem it neccesary, you can save a web page asan HTML file and use scrapy shell by referencing the direct file path to it... So I save you html snippet to a file on my desktop then ran...
scrapy shell file:///home/scriptso/Desktop/letsGREPlol.html
ANYWAYS... as far as xpath... since you asked lol... cake. lets compare the xpath with the cssand tell me you can see... it? lol
response.css('td.tmp_outcome b::text').extract()
so is a td tag....and the class name is tmp_outcome, thn the next node is a bold tag... of which where the text is thusly declaring it as text with the ::text
response.xpath('//td[#class="tmp_outcome"]/b/text()').extract()
So xpath is basically saying we star with a patter inthe entire site of the td tag... and class= tmp_outcome, then the bold, then in xpath to declare type /text() is for text.... /#href is for.. yeah you guessedit
<html>
<tr id="userman-orgchart-tree-node-9" class="fancytree-expanded fancytree-folder fancytree-has-children fancytree-exp-e fancytree-ico-ef">
<td>
<span class="fancytree-node" style="padding-left: 16px;">
<span class="fancytree-expander"></span>
<span class="fancytree-icon"></span>
<span class="fancytree-title">Legal</span>
</span>
</tr>
<tr id="userman-orgchart-tree-node-10" class="fancytree-active fancytree-folder fancytree-has-children fancytree-exp-c fancytree-ico-cf">
<td>
<span class="fancytree-node" style="padding-left: 16px;">
<span class="fancytree-expander"></span>
<span class="fancytree-icon"></span>
<span class="fancytree-title">Branch Performance Test</span>
</span>
</tr>
</html>
Here, in the above case how do I write an element locator to identify the span for Branch Performance Test taking in consideration that tr id could dynamically keep changing to 11 or 12 by adding another record between.
//span[#class='fancytree-title' and text()='Branch Performance Test']/ancestor::span
Above will return all span ancestors of a span with conditions
OR
//span[#class='fancytree-title' and text()='Branch Performance Test']/parent::span
Above will return first span parent of a span with conditions
I want to find the element "Holiday4" in span class="fc-title". How to do it? Do i need to use css selector or do I need to use xpath?
<tr>
<td class="fc-day-number fc-sun fc-future hp-cal-selected" data-date="2016-02-14">14</td>
<td class="fc-day-number fc-mon fc-future" data-date="2016-02-15">15</td>
<td class="fc-day-number fc-tue fc-future" data-date="2016-02-16">16</td>
<td class="fc-day-number fc-wed fc-future" data-date="2016-02-17">17</td>
<td class="fc-day-number fc-thu fc-future" data-date="2016-02-18">18</td>
<td class="fc-day-number fc-fri fc-future" data-date="2016-02-19">19</td>
<td class="fc-day-number fc-sat fc-future" data-date="2016-02-20">20</td>
</tr>
<tr>
<td class="fc-event-container">
<a class="fc-day-grid-event fc-h-event fc-event fc-start fc-end holiday" style="color:65280" title="Holiday">
<div class="fc-content">
<span class="fc-title">Holiday4</span>
</div>
</a>
Use cssSelector
.fc-content [div:contains('Holiday 4')]
Also check this out
Need to find element in selenium by css
https://saucelabs.com/selenium/css-selectors
If to use Python:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get('http://your_url.com')
element = driver.find_element_by_xpath('//span[#class="fc-title"][contain(text(),"Holiday 4")]')
Use Below Xpath,
//span[#class='fc-title'][.='Holiday4']
To get the Text of "Holiday4" you can find it by the following.
Using Css Selector:
string str = driver.FindElement(By.CssSelector("[class='fc-title']")).Text;
Using XPath:
string str = driver.FindElement(By.Xpath("tr/td/a/div/span")).Text;
Here is the html code:
<table>
<tr class="WhiteRow">
<td align="center">
<input id="SelectedDelivery1" type="checkbox" onclick="HandleClick(this.name,this.checked,"")" value="Y" name="SelectedDelivery1">
</td>
<td valign="top">
<span></span>
<span class="bold">Instrument Search</span>
<br>
abc (TRANSFER)
</td>
<td align="center">5 minutes</td>
<td class="noborder" align="right">
<td class="noborder" align="right">
<td class="noborder" align="right">
<td class="noborder" align="right">
</tr>
<tr>
<td align="center">
<input id="SelectedDelivery2" type="checkbox" onclick="HandleClick(this.name,this.checked,"")" value="Y" name="SelectedDelivery1">
</td>
<td valign="top">
<span></span>
<span class="bold">Instrument Search</span>
<br>
abc (CAVEAT)
</td>
...
</tr>
</table>
I would like to target the <tr> containing <span class="bold">Instrument Search</span> and abc (TRANSFER). That tr may not be the first element in the table.
So far I tried
//td/span[text()="Instrument Search"]/ancestor::tr
which only satisfy one of the condition, and there are a few tr that satisfy the selector.
Could you please advise me how to target both of them
Use the following XPath expression:
//tr[contains(., 'abc (TRANSFER)') and contains(td/span[#class = 'bold'], 'Instrument Search')]
If possible, you should always use expressions that are unidirectional, because a "backwards" axis like ancestor:: could be a costly move. That's the advantage over the solution you have found already.
If the span[#class = 'bold'] cannot contain anything else than "Instrument Search", you should modifiy the expression above to:
//tr[contains(., 'abc (TRANSFER)') and td/span[#class = 'bold'] = 'Instrument Search']
The location of "abc (TRANSFER)" is still not very precise, if it is required in a certain place (e.g. always inside a td element) you'd have to further restrict the above.
EDIT Respondin to your comment:
abc (TRANSFER) is inside td tag, it's just a text field
Then use
//tr[contains(td, 'abc (TRANSFER)') and td/span[#class = 'bold'] = 'Instrument Search']
I found myself an answer after crawling through the syntax.
Please let me know if there is any other better ways
//td/span[text()="Instrument Search"]/ancestor::td/text()[contains(., "TRANSFER")]/ancestor::tr