문제

HTML 민첩성 팩을 사용하여 복잡한 웹 페이지에서 테이블을 구문 분석하고 싶지만 객체 모델에서는 어떻게 든 손실됩니다.

링크 예제를 보았지만 이런 식으로 테이블 데이터를 찾지 못했습니다. XPath를 사용하여 테이블을 얻을 수 있습니까? 테이블을 얻는 방법에 대한 데이터를로드 한 후 기본적으로 손실되었습니다. 나는 이전에 Perl에서 이것을 해왔으며 약간 어색했지만 효과가있었습니다. (HTML::TableParser).

구문 분석을위한 올바른 객체 순서에 빛을 비출 수 있다면 나는 또한 행복하다.

도움이 되었습니까?

해결책

다음과 같은 것은 어떻습니까 : 사용 HTML 민첩성 팩

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
foreach (HtmlNode table in doc.DocumentNode.SelectNodes("//table")) {
    Console.WriteLine("Found: " + table.Id);
    foreach (HtmlNode row in table.SelectNodes("tr")) {
        Console.WriteLine("row");
        foreach (HtmlNode cell in row.SelectNodes("th|td")) {
            Console.WriteLine("cell: " + cell.InnerText);
        }
    }
}

원하는 경우 LINQ-to-Objects로 더 예쁘게 만들 수 있습니다.

var query = from table in doc.DocumentNode.SelectNodes("//table").Cast<HtmlNode>()
            from row in table.SelectNodes("tr").Cast<HtmlNode>()
            from cell in row.SelectNodes("th|td").Cast<HtmlNode>()
            select new {Table = table.Id, CellText = cell.InnerText};

foreach(var cell in query) {
    Console.WriteLine("{0}: {1}", cell.Table, cell.CellText);
}

다른 팁

내가 특정 요소에 대해 XPath를 얻는 가장 간단한 것은 Firefox의 FireBug Extension을 설치하는 것입니다. 사이트/웹 페이지 프레스 F12로 이동하여 FireBug를 제기하는 것입니다. 쿼리하려는 페이지의 요소를 오른쪽 선택하고 마우스 오른쪽 버튼으로 클릭하고 "요소 검사"FireBug는 IDE에서 요소를 선택한 다음 FireBug의 요소를 마우스 오른쪽 버튼으로 클릭하고 "XPath 복사"를 선택합니다.이 기능은 정확한 XPATH를 제공합니다. 쿼리 HTML 민첩성 라이브러리를 사용하려는 요소를 가져와야합니다.

나는 이것이 꽤 오래된 질문이라는 것을 알고 있지만 이것은 테이블을 시각화하는 데 도움이 된 내 솔루션으로 클래스 구조를 만들 수 있습니다. 이것은 또한 HTML 민첩성 팩을 사용하고 있습니다

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(@"<html><body><p><table id=""foo""><tr><th>hello</th></tr><tr><td>world</td></tr></table></body></html>");
var table = doc.DocumentNode.SelectSingleNode("//table");
var tableRows = table.SelectNodes("tr");
var columns = tableRows[0].SelectNodes("th/text()");
for (int i = 1; i < tableRows.Count; i++)
{
    for (int e = 0; e < columns.Count; e++)
    {
        var value = tableRows[i].SelectSingleNode($"td[{e + 1}]");
        Console.Write(columns[e].InnerText + ":" + value.InnerText);
    }
Console.WriteLine();
}

제 경우에는 라우터의 장치 목록이있는 단일 테이블이 있습니다. 위에서 언급했듯이 매트릭스 대신 TR/TH/TD (행, 헤더, 데이터)를 사용하여 테이블을 읽으려면 다음과 같은 작업을 수행 할 수 있습니다.

    List<TableRow> deviceTable = (from table in document.DocumentNode.SelectNodes(XPathQueries.SELECT_TABLE)
                                       from row in table?.SelectNodes(HtmlBody.TR)
                                       let rows = row.SelectSingleNode(HtmlBody.TR)
                                       where row.FirstChild.OriginalName != null && row.FirstChild.OriginalName.Equals(HtmlBody.T_HEADER)
                                       select new TableRow
                                       {
                                           Header = row.SelectSingleNode(HtmlBody.T_HEADER)?.InnerText,
                                           Data = row.SelectSingleNode(HtmlBody.T_DATA)?.InnerText}).ToList();
                                       }  

Tablerow는 헤더와 데이터가 속성으로 단순한 객체 일뿐입니다. 이 접근법은 null-sness 와이 사례를 처리합니다.

<tr>
    <td width="28%">&nbsp;</td>
</tr>

헤더가없는 행입니다. 상수가 매달려있는 htmlbody 객체는 아마도 쉽게 추론 될 수 있지만 여전히 사과드립니다. 나는 당신이 당신의 코드에 있다면, 그것은 일정하거나 지역화 할 수있는 세상에서 왔습니다.

위의 답변에서 줄 :

HtmlDocument doc = new HtmlDocument();

이것은 VS 2015 C#에서 작동하지 않습니다. 당신은 구성 할 수 없습니다 HtmlDocument 더 이상.

다른 MS "기능"을 사용하기가 더 어려워집니다. 노력하다 HtmlAgilityPack.HtmlWeb 그리고 체크 아웃 이 링크 일부 샘플 코드의 경우.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top