Pergunta

Eu quero usar o pacote de agilidade HTML para tabelas de análise de páginas da web complexas, mas estou de alguma forma perdido no modelo de objeto.

Eu olhei para o exemplo da ligação, mas não encontrou quaisquer dados da tabela desta forma. Posso usar XPath para obter as tabelas? Estou praticamente perdido depois de ter carregado os dados a respeito de como obter as tabelas. Eu tenho feito isso em Perl antes e foi um pouco desajeitado, mas funcionou. (HTML::TableParser).

Eu também estou feliz se alguém pode simplesmente lançar uma luz sobre o objeto pedido certo para a análise.

Foi útil?

Solução

Como sobre algo como: Usando HTML agilidade pack

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);
        }
    }
}

Note que você pode torná-lo mais bonito com LINQ objetos-to-se você quiser:

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);
}

Outras dicas

O mais simples o que eu encontrei para obter o XPath para um determinado elemento é instalar a extensão Firebug para Firefox ir ao site / página de imprensa F12 para abrir o Firebug; direito, selecione e clique o botão direito no elemento na página que você deseja consultar e selecione "Inspect Element" Firebug irá selecionar o elemento na sua IDE, em seguida, clique direito do Elemento no Firebug e selecione "Copiar XPath" esta função lhe dará o XPath exata consulta que você precisa para obter o elemento que você deseja utilizando Biblioteca agilidade HTML.

Eu sei que esta é uma questão bastante antiga, mas esta foi a minha solução que ajudou com a visualização da mesa para que você pode criar uma estrutura de classe. Isto também está usando a agilidade pacote 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();
}

No meu caso, não há uma única tabela que passa a ser uma lista de dispositivos a partir de um roteador. Se você quiser ler a tabela usando TR / TH / TD (linha, cabeçalho, dados) em vez de uma matriz como mencionado acima, você pode fazer algo como o seguinte:

    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 é apenas um objeto simples com cabeçalho e dados como propriedades. A abordagem cuida de null-ness e neste caso:

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

que é linha sem um cabeçalho. O objeto HTMLBody com as constantes pendurado fora dele são provavelmente prontamente deduzida mas eu pedir desculpas por isso mesmo ainda. Eu vim do mundo onde se tem "em seu código, ele deve quer ser constante ou localizável.

Linha de resposta acima:

HtmlDocument doc = new HtmlDocument();

Isto não funciona no VS 2015 C #. Você não pode construir uma HtmlDocument mais.

Outra "recurso" MS que torna as coisas mais difíceis de usar. Tente HtmlAgilityPack.HtmlWeb e confira este link para um código de exemplo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top