使用HAP(HTML Agility Pack)從頁面獲取數據

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

這篇文章的延續,我試圖從HTML頁面解析一些數據。這是HTML(頁面上有更多信息,但這是重要部分):

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

我需要得到兩條信息:Queue下面的td內的數據和Wait下面的td內的數據(所以隊列計數和等待時間)。顯然這些數字會經常更新。

我已經到了HTML被填充到HtmlDocument變量的地步。我發現了一些使用HtmlNodeCollection來收集符合特定條件的節點。這基本上是我陷入困境的地方:

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

我可以用foreach來解決這個問題,但我不確定如何訪問該值或如何獲取下一個值。

一般承認的答案

一般來說,沒有必要經常使用foreach因為獲取目標信息非常簡單(使用foreach你必須管理循環的每次迭代的狀態,而且它真的很笨重)。

首先,你想得到這張桌子。過濾class屬性通常是個壞主意,因為HTML文檔中有多個元素可以應用它。如果你有一個id屬性,那將是理想的。

也就是說,如果這是這個類的唯一表,那麼你可以使用以下方法獲取table元素的主體:

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

從那裡,您想要獲得各行。由於這些是tbody元素的直接子元素,因此您可以通過ChildNodes屬性按位置獲取行,如下所示:

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

然後你想要每行中的第二個td元素。雖然在那裡有一個包含內容的span標記,但是你想要整個 td元素中的所有文本,你可以使用InnerText屬性來獲取值:

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

注意,這裡有復制,所以如果你發現有很多行需要像這樣解析,你可能想要將一些邏輯分解為輔助方法。


熱門答案

您也可以使用CsQuery來執行此操作。由於它使用熟悉的CSS選擇器語法和jQuery方法,因此對於更複雜的DOM導航,它比HAP更容易使用。例如:

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



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因