HtmlAgilityPack Lesen von Daten von einer HTML-Seite

c# html-agility-pack

Frage

Ich versuche, Daten aus einer HTML-Tabelle mit HTML Agility Pack zu bekommen, aber immer nur die Daten in der ersten Tabellenzeile.

Der HTML-Code, von dem ich lese, ist der folgende:

<div id="mainDiv">
    <table id="tbl">
        <thead>
            <tr>
                <th class="tbl_col1">UserName</th>
                <th class="tbl_col2">Points</th>
            </tr>
        </thead>
        <tbody>     
          <tr data-source="provider1">
            <td class="tbl_col1">
                <a href="/Users/1090" id="UserLink" target="_blank">UserName1</a>           
            </td>
            <td class="tbl_col2">
                <a href="/UserPoints/1090" id="PointLink" target="_blank">1892 <span class="up_arrow">&nbsp;</span></a>             
            </td>           
          </tr>
          <tr data-source="provider2">
            <td class="tbl_col1">
                <a href="/Users/1090" id="UserLink" target="_blank">UserName2</a>           
            </td>
            <td class="tbl_col2">
                <a href="/UserPoints/1090" id="PointLink" target="_blank">3217 <span class="down_arrow">&nbsp;</span></a>               
            </td>           
         </tr>
        </tbody>
    </table>
</div>  

Ich benutze diesen Code

var UserTable = htmlDocument.DocumentNode.SelectSingleNode("//div[@id='mainDiv']").SelectSingleNode("//table[@id='tbl']").SelectSingleNode("//tbody").SelectNodes("//tr");
foreach (var row in UserTable)
{
    if (row.Attributes["data-source"] != null)
    {
        string Source = row.Attributes["data-source"].Value;
        string UserName = row.SelectSingleNode("td[@class='tbl_col1']").SelectSingleNode("//a[@id='UserLink']/text()").InnerText;
        string Points = row.SelectSingleNode("td[@class='tbl_col2']").SelectSingleNode("//a[@id='PointLink']/text()").InnerText;
        Console.WriteLine(Source + "\t" + UserName + "\t" + Points);
    }
}

Aber ich bekomme immer diese Ausgabe:

provider1       UserName1       1892
provider2       UserName1       1892

Akzeptierte Antwort

Sie haben falsche Annahmen getroffen: //a[@id='UserLink']/text() und //a[@id='PointLink']/text() durchsucht das gesamte Dokument. Deshalb bekommst du den ersten tr Knoten. Benutz einfach:

string UserName = row.SelectSingleNode("td[@class='tbl_col1']/a[@id='UserLink']/text()").InnerText;
string Points = row.SelectSingleNode("td[@class='tbl_col2']/a[@id='PointLink']/text()").InnerText;

Außerdem können Sie den Rest Ihres Codes wirklich vereinfachen:

var UserTable = doc.DocumentNode.SelectNodes("//div[@id='mainDiv']/table[@id='tbl']/tbody/tr");
foreach (var row in UserTable)
{
    if (row.Attributes["data-source"] != null)
    {
        string Source = row.Attributes["data-source"].Value;
        string UserName = row.SelectSingleNode("td[@class='tbl_col1']/a[@id='UserLink']/text()").InnerText;
        string Points = row.SelectSingleNode("td[@class='tbl_col2']/a[@id='PointLink']/text()").InnerText;
        Console.WriteLine(Source + "\t" + UserName + "\t" + Points);
    }
}


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum