Obtenir des données en utilisant HAP (HTML Agility Pack) De la page

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

Question

Suite de ce post , j'essaie d'analyser certaines données d'une page HTML. Voici le code HTML (il y a plus d'informations sur la page, mais c'est la section importante):

<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>

J'ai besoin d'obtenir 2 informations: les données à l'intérieur de la file d'attente en dessous de td et les données à l'intérieur de l'attente en dessous de td (le nombre de files d'attente et le temps d'attente sont donc comptés). De toute évidence, les chiffres vont être mis à jour fréquemment.

Je suis arrivé au point où le code HTML est inséré dans une variable HtmlDocument. Et j'ai trouvé quelque chose dans le genre d'utilisation d'un HtmlNodeCollection pour rassembler des noeuds qui répondent à certains critères. Ceci est essentiellement où je suis coincé:

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.
     */
}

Et je peux passer à travers cela avec un foreach , mais je ne suis pas sûr de savoir comment accéder à la valeur ou comment obtenir la valeur suivante.

Réponse acceptée

Généralement, il n’est pas nécessaire de passer à l’avant avec un foreach car obtenir l’information ciblée est assez facile (avec un foreach vous devez gérer l’état de chaque itération de la boucle et c’est vraiment compliqué).

Tout d'abord, vous voulez avoir la table. Filtrer sur l'attribut de class est généralement une mauvaise idée, car vous pouvez avoir plusieurs éléments dans un document HTML auxquels la classe est appliquée. Si vous aviez un attribut id , ce serait idéal.

Cela dit, s'il s'agit de la seule table avec cette classe, vous pouvez obtenir le corps de l'élément table utilisant:

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

A partir de là, vous voulez obtenir les lignes individuelles. Comme il s'agit d'enfants directs de l'élément tbody , vous pouvez obtenir les lignes par position via la propriété ChildNodes , comme ChildNodes :

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

Ensuite, vous voulez le deuxième élément td dans chaque ligne. Bien qu'il y ait une balise span qui englobe le contenu, vous voulez que tout le texte de l'élément td soit intégralement, vous pouvez utiliser la propriété InnerText pour obtenir la valeur:

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

Notez qu'il existe une réplication ici. Par conséquent, si vous rencontrez de nombreuses lignes que vous devez analyser de cette façon, vous voudrez peut-être intégrer une partie de la logique aux méthodes d'assistance.


Réponse populaire

Vous pouvez également utiliser CsQuery pour le faire. Comme il utilise la syntaxe bien connue du sélecteur CSS et les méthodes jQuery, il peut être plus facile à utiliser que HAP pour une navigation DOM plus complexe. Par exemple:

// 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
}


Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow