Holen Sie Daten mit HAP (HTML Agility Pack) von Seite

.net .net-4.0 c# html-agility-pack

Frage

Eine Fortsetzung dieses Posts , ich versuche, einige Daten von einer HTML-Seite zu analysieren. Hier ist der HTML (es gibt mehr Informationen auf der Seite, aber das ist der wichtige Abschnitt):

<table class="integrationteamstats">
<tbody>
<tr>
    <td class="right">
        <span class="mediumtextBlack">Queue:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0</span>
    </td>
    <td class="right">
        <span class="mediumtextBlack">Aban:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0%</span>
    </td>
    <td class="right">
        <span class="mediumtextBlack">Staffed:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0</span>
    </td>
</tr>
<tr>
    <td class="right">
        <span class="mediumtextBlack">Wait:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0:00</span>
    </td>
    <td class="right">
        <span class="mediumtextBlack">Total:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0</span>
    </td>
    <td class="right">
        <span class="mediumtextBlack">On ACD:</span>
    </td>
    <td class="left">
        <span class="mediumtextBlack">0</span>
    </td>
</tr>
</tbody>
</table>

Ich muss 2 Stücke von Informationen erhalten: die Daten innerhalb der td unter Warteschlange und die Daten in der td unter Warten (also die Warteschlange Anzahl und Wartezeit). Offensichtlich werden die Zahlen häufig aktualisiert.

Ich bin an den Punkt gelangt, an dem der HTML-Code in eine HtmlDocument-Variable umgewandelt wird. Und ich habe etwas in der Art gefunden, eine HtmlNodeCollection zu verwenden, um Knoten zu sammeln, die bestimmte Kriterien erfüllen. Dies ist im Grunde, wo ich feststecke:

HtmlNodeCollection tds = 
    new HtmlNodeCollection(this.html.DocumentNode.ParentNode);
tds = this.html.DocumentNode.SelectNodes("//td");

foreach (HtmlNode td in tds)
{
    /* I want to write:
     * If the last node's value was 'Queue', give me the value of this node.
     * and
     * If the last node's value was 'Wait Time', give me the value of this node.
     */
}

Und ich kann das mit einer foreach durchgehen, aber ich bin mir nicht sicher, wie ich auf den Wert zugreifen oder wie ich den nächsten Wert bekommen soll.

Akzeptierte Antwort

Im Allgemeinen ist es nicht notwendig, mit einer foreach da die Zielinformationen ziemlich einfach sind (mit einer foreach müsste man den Zustand jeder Iteration der Schleife verwalten, und es ist wirklich unhandlich).

Zuerst möchtest du den Tisch bekommen. Das Filtern des class ist im Allgemeinen eine schlechte Idee, da Sie mehrere Elemente in einem HTML-Dokument haben können, auf die die Klasse angewendet wird. Wenn Sie ein id Attribut hätten, wäre das ideal.

Das heißt, wenn dies die einzige Tabelle mit dieser Klasse ist, dann können Sie den Hauptteil des table verwenden:

// Get the table.
HtmlNode tableBody = document.DocumentNode.SelectSingleNode(
    "//table[@class='integrationteamstats']/tbody");

Von dort wollen Sie die einzelnen Zeilen erhalten. Da diese direkt tbody Elemente des tbody Elements sind, können Sie die Zeilen wie ChildNodes über die ChildNodes Eigenschaft nach Position ChildNodes :

HtmlNode queueRow = tableBody.ChildNodes[0];
HtmlNode waitRow = tableBody.ChildNodes[1];

Dann wollen Sie das zweite td Element in jeder Zeile. Es gibt zwar ein span Tag, das den Inhalt InnerText , aber Sie möchten, dass der gesamte Text, der sich im td Element befindet, vollständig ist. Sie können die InnerText Eigenschaft verwenden, um den Wert zu erhalten:

string queueValue = queueRow.ChildNodes[1].InnerText;
string waitValue = waitRow.ChildNodes[1].InnerText;

Beachten Sie, dass es hier eine Replikation gibt. Wenn Sie also feststellen, dass viele Zeilen so analysiert werden müssen, möchten Sie möglicherweise einen Teil der Logik in Hilfsmethoden ausklammern.


Beliebte Antwort

Sie können dazu auch CsQuery verwenden. Da es vertraute CSS-Selector-Syntax und jQuery-Methoden verwendet, kann es für komplexere DOM-Navigation einfacher zu verwenden sein als HAP. Beispielsweise:

// function to get the text from the cell AFTER the one containing 'text'

string getNextCellText(CQ dom, string text) {
    // find the target cell
    CQ target= dom.Select(".integrationteamstats td:contains(" + text + ")");

    // return the text contents of the next cell
    return target.Next().Text();
}

void Main() {
    var dom = CQ.Create(html);
    string queue = getNextCellText(dom,"Queue");
    string wait = getNextCellText(dom,"Wait:");

    .. do stuff
}



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