Como usar o pacote HTML Agility


629

Como uso o HTML Agility Pack ?

Meu documento XHTML não é totalmente válido. É por isso que eu queria usá-lo. Como eu o uso no meu projeto? Meu projeto está em c #.


79
Esta pergunta foi muito útil para mim.
BigJoe714

26
Nota: com um Visual Studio que lida com o NuGet, agora você pode clicar com o botão direito do mouse em "Referências" e escolher "Gerenciar pacotes NuGet ...", pesquise "HtmlAgilityPack" e clique em "Instalar". Em seguida, comece a jogar com o código com uma instrução using / Import.
28411 patridge

Com relação ao comentário acima de @patridge: descobri que precisava remover e adicionar novamente minha referência ao HtmlAgilityPack ao buscar o projeto pela primeira vez em svn via ankhsvn.
Andrew Coonce

14
Qualquer pessoa que procure o HTMLAgilityPack deve considerar o CsQuery, é uma biblioteca muito mais nova com uma interface muito mais moderna da minha experiência. Por exemplo, o código inteiro da primeira resposta pode ser resumido no CsQuery como var body = CQ.CreateFromFile(filePath)["body"].
Benjamin Gruenbaum 01/01

2
@BenjaminGruenbaum: perfeito para a sua sugestão CsQuery - configurada em minutos, muito fácil de usar.
Neolisk

Respostas:


358

Primeiro, instale o pacote de nuget HTMLAgilityPack no seu projeto.

Então, como um exemplo:

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

// There are various options, set as needed
htmlDoc.OptionFixNestedTags=true;

// filePath is a path to a file containing the html
htmlDoc.Load(filePath);

// Use:  htmlDoc.LoadHtml(xmlString);  to load from a string (was htmlDoc.LoadXML(xmlString)

// ParseErrors is an ArrayList containing any errors from the Load statement
if (htmlDoc.ParseErrors != null && htmlDoc.ParseErrors.Count() > 0)
{
    // Handle any parse errors as required

}
else
{

    if (htmlDoc.DocumentNode != null)
    {
        HtmlAgilityPack.HtmlNode bodyNode = htmlDoc.DocumentNode.SelectSingleNode("//body");

        if (bodyNode != null)
        {
            // Do something with bodyNode
        }
    }
}

(Nota: este código é apenas um exemplo e não necessariamente a melhor / única abordagem. Não o use cegamente em seu próprio aplicativo.)

O HtmlDocument.Load()método também aceita um fluxo que é muito útil na integração com outras classes orientadas a fluxo na estrutura .NET. While HtmlEntity.DeEntitize()é outro método útil para processar corretamente entidades html. (obrigado Matthew)

HtmlDocumente HtmlNode são as classes que você mais usará. Semelhante a um analisador XML, ele fornece os métodos selectSingleNode e selectNodes que aceitam expressões XPath.

Preste atenção às HtmlDocument.Option?????? propriedades booleanas. Eles controlam como os métodos Loade LoadXMLirão processar seu HTML / XHTML.

Há também um arquivo de ajuda compilado chamado HtmlAgilityPack.chm que possui uma referência completa para cada um dos objetos. Normalmente, isso está na pasta base da solução.


11
Observe também que o Load aceita um parâmetro Stream, o que é conveniente em muitas situações. Eu usei para um fluxo HTTP (WebResponse.GetResponseStream). Outro bom método para conhecer é o HtmlEntity.DeEntitize (parte do HTML Agility Pack). Isso é necessário para processar entidades manualmente em alguns casos.
Matthew Flaschen

1
nota: na versão beta mais recente do Html Agility Pack (1.4.0 Beta 2 lançado em 3 de outubro de 2009), o arquivo de ajuda foi transferido para um download separado devido às dependências do Sandcastle, DocProject e Visual Studio 2008 SDK.
precisa saber é o seguinte

SelectSingleNode() parece ter sido removido há um tempo atrás
Chris S

3
Não, SelectSingleNode e SelectNodes definitivamente ainda estão lá. Acho que é um pouco interessante que ele deve ser htmlDoc.ParseErrors.Count (), não. Count
Mike Blandford

1
@MikeBlandford // Parcialmente sim. Parece ter sido removido (ou não existia desde o início) na versão PCL do HtmlAgailityPack. nuget.org/packages/HtmlAgilityPack-PCL
Joon Hong

166

Não sei se isso ajudará você, mas escrevi alguns artigos que apresentam o básico.

O próximo artigo está 95% completo, basta escrever explicações das últimas partes do código que escrevi. Se você estiver interessado, tentarei me lembrar de postar aqui quando publicá-lo.


16
Finalmente terminou esse artigo dois anos mais tarde :) Um método simples para detectar feeds RSS e Atom em sites com HtmlAgilityPack
rtpHarry

3
Recentemente, no Code Project , foi lançado um artigo muito bom do HTMLAgilityPack. Você pode lê-lo aqui #
Victor Sigler

64

O HtmlAgilityPack usa a sintaxe XPath e, embora muitos argumentem que está mal documentado, não tive problemas em usá-lo com a ajuda desta documentação do XPath: https://www.w3schools.com/xml/xpath_syntax.asp

Para analisar

<h2>
  <a href="">Jack</a>
</h2>
<ul>
  <li class="tel">
    <a href="">81 75 53 60</a>
  </li>
</ul>
<h2>
  <a href="">Roy</a>
</h2>
<ul>
  <li class="tel">
    <a href="">44 52 16 87</a>
  </li>
</ul>

Eu fiz isso:

string url = "http://website.com";
var Webget = new HtmlWeb();
var doc = Webget.Load(url);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//h2//a"))
{
  names.Add(node.ChildNodes[0].InnerHtml);
}
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//li[@class='tel']//a"))
{
  phones.Add(node.ChildNodes[0].InnerHtml);
}

Completamente verdade. É totalmente dependente do XPathpadrão. Deve-se primeiro aprender esse padrão e tudo será fácil depois disso.
FindOut_Quran

O link que você forneceu não está mais disponível. Este é provavelmente o novo: w3schools.com/xsl/xpath_syntax.asp
Piotrek

Também não consigo ver nenhuma função SelectNodes () no objeto DocumentNode. É renomeado?
Piotrek

Qual versão você está usando e de onde baixou? De acordo com htmlagilitypack.codeplex.com/SourceControl/latest#Release/1_4_0/… , deve haver um método SelectNodes na classe HtmlNode.
Kent Munthe Caspersen

Fazer a ligação não estiver disponível, novo link: www.w3schools.com/xml/xpath_syntax.asp
Tyrmos

6

O principal código relacionado ao HTMLAgilityPack é o seguinte

using System;
using System.Net;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;
using System.Text.RegularExpressions;
using HtmlAgilityPack;

namespace GetMetaData
{
    /// <summary>
    /// Summary description for MetaDataWebService
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class MetaDataWebService: System.Web.Services.WebService
    {
        [WebMethod]
        [ScriptMethod(UseHttpGet = false)]
        public MetaData GetMetaData(string url)
        {
            MetaData objMetaData = new MetaData();

            //Get Title
            WebClient client = new WebClient();
            string sourceUrl = client.DownloadString(url);

            objMetaData.PageTitle = Regex.Match(sourceUrl, @
            "\<title\b[^>]*\>\s*(?<Title>[\s\S]*?)\</title\>", RegexOptions.IgnoreCase).Groups["Title"].Value;

            //Method to get Meta Tags
            objMetaData.MetaDescription = GetMetaDescription(url);
            return objMetaData;
        }

        private string GetMetaDescription(string url)
        {
            string description = string.Empty;

            //Get Meta Tags
            var webGet = new HtmlWeb();
            var document = webGet.Load(url);
            var metaTags = document.DocumentNode.SelectNodes("//meta");

            if (metaTags != null)
            {
                foreach(var tag in metaTags)
                {
                    if (tag.Attributes["name"] != null && tag.Attributes["content"] != null && tag.Attributes["name"].Value.ToLower() == "description")
                    {
                        description = tag.Attributes["content"].Value;
                    }
                }
            } 
            else
            {
                description = string.Empty;
            }
            return description;
        }
    }
}

4
O site não está mais disponível #
Dimitar Tsonev

5
    public string HtmlAgi(string url, string key)
    {

        var Webget = new HtmlWeb();
        var doc = Webget.Load(url);
        HtmlNode ourNode = doc.DocumentNode.SelectSingleNode(string.Format("//meta[@name='{0}']", key));

        if (ourNode != null)
        {


                return ourNode.GetAttributeValue("content", "");

        }
        else
        {
            return "not fount";
        }

    }

0

Introdução - HTML Agility Pack

// From File
var doc = new HtmlDocument();
doc.Load(filePath);

// From String
var doc = new HtmlDocument();
doc.LoadHtml(html);

// From Web
var url = "http://html-agility-pack.net/";
var web = new HtmlWeb();
var doc = web.Load(url);

0

tente isso

string htmlBody = ParseHmlBody(dtViewDetails.Rows[0]["Body"].ToString());

private string ParseHmlBody(string html)
        {
            string body = string.Empty;
            try
            {
                var htmlDoc = new HtmlDocument();
                htmlDoc.LoadHtml(html);
                var htmlBody = htmlDoc.DocumentNode.SelectSingleNode("//body");
                body = htmlBody.OuterHtml;
            }
            catch (Exception ex)
            {

                dalPendingOrders.LogMessage("Error in ParseHmlBody" + ex.Message);
            }
            return body;
        }
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.