skrape.it process rows of a table by itself - kotlin

I am new to the skrape.it library and try to extract content of a table.
Is there a way to process every table by it self, so I get a List with all texts of a row in a List with all rows? e.g.: List<List>
My current approach is to get all texts from every td and count all tr and then process these two lists by calculating the index of the required text.
One row looks like this:
<tr role="row">
<td class="grad" style="background:#067A25; width:50px">
<div class="grad_outer">
<span>4c</span>
</div>
</td>
<td class="name">
King Louie
</td>
<td>
Dave
</td>
<td>
11.03.2022
</td>
<td>
12
</td>
<td>
64.2
</td>
</tr>
I also need to extract the background css attribute of each first td tag. How can I do this?

Related

How can I get the XPATH of elements under all rows of the same rowspan?

Test data:
<table>
<tbody>
<tr>
<td id="mainfield:1" rowspan="3">A1</td>
<td ><span class="searching_for_this"> AA1</span></td>
<td ><span class="not_searching_for_this">AA2</span></td>
</tr>
<tr>
<td ><span class="searching_for_this"> AA3 </span></td>
<td ><span class="not_searching_for_this">AA3 </span></td>
</tr>
<tr>
<td ><span class="searching_for_this"> AA1 </span></td>
<td ><span class="not_searching_for_this">AA4 </span></td>
</tr>
<tr>
<td id="main_field:2" rowspan="3">B1</td>
<td ><span class="searching_for_this"> BB1</span></td>
<td ><span class="not_searching_for_this">BB2</span></td>
</tr>
<tr>
<td ><span class="searching_for_this"> AA1 </span></td>
<td ><span class="not_searching_for_this">BB3 </span></td>
</tr>
<tr>
<td ><span class="searching_for_this"> BB2 </span></td>
<td ><span class="not_searching_for_this">BB3 </span></td>
</tr>
</tbody>
</table>
Premises
I know the content of the row and column where 3 rowspan is located, (in this example A1)
I now the content of one element of the class I want to look for, in this scenario AA1 and searching_for_this
I want to get the rows (tr) of AA1 under the rowspan of A1. So the result would be the first and third row
First try
So in a single row scenario this would be something like:
Main row: //tr[td[contains(text(), 'A1')]]
Search in the children from the row (relative search .//):
.//tr[td/span[class=searching_for_this and contains(text(), 'AA1')]]
Problem
With this rowspan scenario I don't know how can I get all elements taking into account "next rows" after colspan without including the rows outside the colspan (B1).
Update
After the last answer I tried to build from there, but I'm still not able to get the rows under the main row span row to build the query combine with the main row. This was my try
$x("//tr[ (preceding-sibling::tr[ .//td[ contains(#id, 'main_field')]])[1][.//td[contains(text(),'A1')]] ]")
I tried to get all tr that have a preceding sibling tr with the given known partial id, take the first one of that list with [0] (direct sibling with the given id) then filter with the content A1. But I do not get anything.
If you want to do this in a single expression in XPath 1.0, it gets a bit complex. You could approach it like this, building it piece by piece.
As a starting point, here's how you select your "main row":
//tr[td[contains(text(),'A1')]]
Building on this, you can select the following rows within the same rowspan:
//tr[td[contains(text(),'A1')]]
/following-sibling::tr[
position() < number(preceding-sibling::tr/td[contains(text(),'A1')]/#rowspan)
]
However, this does not include the "main row" itself. To get it also, you can take a union of both of the above with the union operator (|), so you get both the main row and the following rows that fall within the the same rowspan:
(//tr[td[contains(text(),'A1')]]
|//tr[td[contains(text(),'A1')]]
/following-sibling::tr[
position() < number(preceding-sibling::tr/td[contains(text(),'A1')]/#rowspan)
]
)
Now that you have the set of rows of interest at hand, you can further narrow down to the rows that you want within that set, e.g.:
(//tr[td[contains(text(),'A1')]]
|//tr[td[contains(text(),'A1')]]
/following-sibling::tr[
position() < number(preceding-sibling::tr/td[contains(text(),'A1')]/#rowspan)
]
)[td/span[#class='searching_for_this' and contains(text(), 'AA1')]]

iterate with v-for and data-attribute

I have a vuejs-datatable, and now I want to have an option-column with edit- / delete-links.
This is the table-body which gets iterated from the function getRows():
<tbody>
<tr v-for="(row, idr) in get_rows()" v-bind:key="idr">
<td>{{row.id}}</td>
<td>{{row.email}}</td>
<td>
<b-icon-pencil-square></b-icon-pencil-square>
<b-icon-trash></b-icon-trash>
</td>
</tr>
</tbody>
Now the td with the {{row.id}} and {{row.email}} are fine. However the :data-id="row.id" displays only the id of the first entry. Links in every row in my table have the same data-id. I do not understand why this is happening and what am I doing wrong.
Use code below (notice, it's not using data-id):
<tbody>
<tr v-for="(row, idr) in get_rows()" v-bind:key="idr">
<td>{{row.id}}</td>
<td>{{row.email}}</td>
<td>
<b-icon-pencil-square></b-icon-pencil-square>
<b-icon-trash></b-icon-trash>
</td>
</tr>
</tbody>

Create relationship between 2 tds- Selenium Java

I am trying to collect the values - name, quantity, price per KG and total in HashMap. I can use the following 2 items to collect name and quantity
private By productName = By.xpath("//td//p[#class='product-name']");
private By productQuantity = By.xpath("//td//p[#class='quantity']");
Problem: When I try //td//p[#class='amount'] it ends up selecting 4. A few options I have been experimenting are select the 2nd td related to product name which will give me price per kg //td//p[#class='product-name']/following-sibling:://td[2] or //td//p[#class='product-name']/ancestor::td
None of them are working.Any clue what I can use here? Thanks in advance for your time.
Source:
<tr>
<td><img class="product-image" src="./images/cucumber.jpg" style="width: 50px; height: 50px;"></td>
<td>
<td>
<p class="product-name">Cucumber - 1 Kg</p>
</td>
<p class="quantity">2</p>
</td>
<td>
<p class="amount">48</p>
</td>
<td>
<p class="amount">96</p>
</td>
</tr>
If you want to get value of 96 the use Following xpath
//td[.//p[#class='product-name']]/following::td[2]/p
OR
//td[.//p[#class='product-name']]/following-sibling::td[2]/p

Selenium XPath multiple selection

I want to find all elements in the table that match the following conditions:
-div text contains '2019';
-div class='excellent';
here is the HTML code excerpt:
<tr>
<td>Name of Person1</td>
<td>
<div class="testDate">21/12/2019</div>
<div class="excellent"></div>
</td>
</tr>
<tr>
<td>Name of Person2</td>
<td>
<div class="testDate">01/12/2017</div>
</td>
</tr>
I tried this solution:
//tr/td[2][div/text()='21/12/2019'][div[#class='starred']]
but I need the year only and not entirely date.
Use the below xpath.
//tr/td[div[contains(.,'2019')]and div[#class='excellent']]
Screenshot:

Selenium, Unable to find element by containing text following child node

A little bit of background:
The HTML looks like this:
<table>
<thead>
<tr>
<th>Head1</th>
<th>Head2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span>
<span class="icon">S</span>
"Auto"
</span>
</td>
<td>
<span>
Cost, Time
</span>
</td>
</tr>
</tbody>
</table>
A simple version of the code looks like this: (run in pry)
[69] pry> e = driver.find_element(:xpath, "//table/tbody/tr/td/span")
=> #<Selenium::WebDriver::Element:0x7ba9a4d694458ec id=":wdc:1361791490676">
[70] pry> e.text
=> "SAutomotive"
[71] pry> e = driver.find_element(:xpath, "//table/tbody/tr/td/span[contains(text(),'Auto')]")
Selenium::WebDriver::Error::NoSuchElementError: The element could not be found
from /Users/ben/.rvm/gems/ruby-1.9.3-p194/gems/selenium-webdriver-2.29.0/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'
I have no access to changing the HTML code
Although there is only one row in this table there is the possibility of more being added and I cannot predict the location of the row, this is why i am trying to find it by name
my normal code is:
e = driver.find_element(:xpath, "//table/tbody/tr[td/span[contains(text(),'Auto')]]")
The problem I am having is that I cannot find any way of getting the row in the table by the name given in the text of the first table cell.
Use below xpath
"//table/tbody/tr/td/span[contains(.,'Auto')]"