HAP (HTML 민첩성 팩)을 사용하여 데이터 가져 오기

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

나는 2 가지 정보를 얻을 필요가있다 : 큐 아래의 td 내부의 데이터와 큐 아래의 td 데이터 (대기열 수와 대기 시간). 분명히 숫자가 자주 업데이트 될 것입니다.

HTML이 HtmlDocument 변수에 채워지는 지점에 이르렀습니다. 그리고 HtmlNodeCollection을 사용하여 특정 기준을 충족하는 노드를 모으는 과정에서 뭔가를 발견했습니다. 이것은 기본적으로 내가 붙어있는 곳입니다 :

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

foreach 를 사용하여이 작업을 수행 할 수 있지만 값에 액세스하는 방법이나 다음 값을 얻는 방법을 알 수는 없습니다.

수락 된 답변

일반적으로, 끝까지 갈 필요가 없습니다 foreach 대상 정보를 얻는 것은 (A 꽤 쉽기 때문에 foreach 당신이 루프의 각 반복의 상태를 관리해야 할 것 그리고 정말 다루기 힘든이다가).

먼저, 테이블을 얻고 싶습니다. class 속성이 적용된 HTML 문서에서 여러 요소를 가질 수 있으므로 class 속성에 대한 필터링은 일반적으로 좋지 않습니다. id 속성이 있다면 이상적입니다.

즉, 이것이이 클래스의 유일한 테이블 인 경우 다음을 사용하여 table 요소의 본문을 가져올 수 있습니다.

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

거기에서 개별 행을 가져 오려고합니다. 이것들은 tbody 요소의 직접 자식이기 때문에, 다음과 같이 ChildNodes 속성을 통해 위치별로 행을 얻을 수 있습니다.

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

그런 다음 각 행에 두 번째 td 요소가 필요합니다. 거기에 내용을 감싸는 span 태그가 있지만, td 요소에있는 모든 텍스트를 전체적으로 원하면 InnerText 속성을 사용하여 값을 가져올 수 있습니다.

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

여기에는 복제가 있습니다. 따라서 이처럼 구문 분석해야하는 행이 많으면 일부 논리를 도우미 메소드로 분해해야 할 수 있습니다.


인기 답변

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는 합법적입니까? 예, 이유를 알아보십시오.