Html Agility Pack Loop Through Table - Get cell value based on previous cell value

c# html-agility-pack phantomjs selenium-webdriver web-scraping

Question

I have many tables, and each table's Location Value has a distinct index order. When I loop over the table, how do I acquire the location value if the preceding cell text is "Location"? In the example below, the cells are [7], while in the other table, they are [9]. How can I retrieve data just if the inner text of the cell is "Location"? Find the cell labeled "Location" and then retrieve the following cell's inner text.

Table in HTML:

<table class="tbfix FieldsTable"">
<tbody>
    <tr>
        <td class="name">Last Movement</td>
        <td class="value">Port Exit</td>
    </tr>
    <tr>
        <td class="name">Date</td>
        <td class="value">26/06/2017 00:00:00</td>
    </tr>
    <tr>
        <td class="name">From</td>
        <td class="value">HAMBURGE</td>
    </tr>
    <tr>
        <td class="name">Location</td>
        <td class="value">EUROGATE  HAMBURG</td>
    </tr>
    <tr>
        <td class="name">E/F</td>
        <td class="value">E</td>
    </tr>
</tbody>

Loop Through for Controller:

foreach (var eachNode in driver.FindElements(By.XPath("//table[contains(descendant::*, 'Last Movement')]")))
                {
                    var cells = eachNode.FindElements(By.XPath(".//td"));
                    cd = new Detail();

                    for (int i = 0; i < cells.Count(); i++)
                    {
                        cd.ActionType = cells[1].Text.Trim();
                        string s = cells[3].Text.Trim();
                        DateTime dt = Convert.ToDateTime(s);
                        if (_minDate > dt) _minDate = dt;
                        cd.ActionDate = dt;

                    }
                }
1
0
7/13/2017 9:46:19 PM

Accepted Answer

You may use this in your foreach loop:

var location = eachNode.FindElement(By.XPath(".//td[contains(text(),'Location')]/following-sibling::td));
1
7/13/2017 11:34:21 PM

Popular Answer

In the event that your data is consistently organized in this manner, I would iterate over each tag and add the information to a dictionary.

As an example, try this:

Dictionary<string,string> tableData = new Dictionary<string, string>();
var trNodes = eachNode.FindElements(By.TagName("tr"));

foreach (var trNode in trNodes)
{
    var name = trNode.FindElement(By.CssSelector(".name")).Text.Trim();
    var value = trNode.FindElement(By.CssSelector(".value")).Text.Trim();

    tableData.Add(name,value);
}

var location = tableData["location"];

The structure and dictionary would need more validation, but that is the fundamental concept.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow