Come usare il pacchetto di agilità HTML


629

Come si usa HTML Agility Pack ?

Il mio documento XHTML non è completamente valido. Ecco perché volevo usarlo. Come lo uso nel mio progetto? Il mio progetto è in C #.


79
Questa domanda mi è stata molto utile.
BigJoe714,

26
Nota a margine: con un Visual Studio che gestisce NuGet, ora è possibile fare clic con il pulsante destro del mouse su "Riferimenti" e scegliere "Gestisci pacchetti NuGet ...", cercare "HtmlAgilityPack" e fare clic su "Installa". Quindi inizia a giocare con il codice con un'istruzione using / Import.
Patridge,

Per quanto riguarda il commento sopra di @patridge: ho scoperto che dovevo rimuovere e quindi aggiungere nuovamente il mio riferimento a HtmlAgilityPack quando ho recuperato il progetto da svn tramite ankhsvn.
Andrew Coonce,

14
Chiunque cerchi HTMLAgilityPack dovrebbe considerare CsQuery, è una libreria molto più recente con un'interfaccia molto più moderna dalla mia esperienza. Ad esempio, l'intero codice della prima risposta può essere riassunto in CsQuery come var body = CQ.CreateFromFile(filePath)["body"].
Benjamin Gruenbaum,

2
@BenjaminGruenbaum: pollice in alto per il tuo suggerimento CsQuery - impostato in pochi minuti, molto facile da usare.
Neolisk,

Risposte:


358

Innanzitutto, installa il pacchetto nuget HTMLAgilityPack nel tuo progetto.

Quindi, ad esempio:

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

(NB: questo codice è solo un esempio e non necessariamente l'approccio migliore / unico. Non utilizzarlo ciecamente nella propria applicazione.)

Il HtmlDocument.Load()metodo accetta anche un flusso che è molto utile per l'integrazione con altre classi orientate al flusso nel framework .NET. Mentre HtmlEntity.DeEntitize()è un altro metodo utile per elaborare correttamente le entità html. (grazie Matteo)

HtmlDocumente HtmlNode sono le classi che utilizzerai di più. Simile a un parser XML, fornisce i metodi selectSingleNode e selectNodes che accettano le espressioni XPath.

Presta attenzione alle HtmlDocument.Option?????? proprietà booleane. Questi controllano come i metodi Loade LoadXMLelaboreranno il tuo HTML / XHTML.

Esiste anche un file di aiuto compilato chiamato HtmlAgilityPack.chm che ha un riferimento completo per ciascuno degli oggetti. Normalmente si trova nella cartella di base della soluzione.


11
Si noti inoltre che Load accetta un parametro Stream, utile in molte situazioni. L'ho usato per un flusso HTTP (WebResponse.GetResponseStream). Un altro buon metodo di cui tenere conto è HtmlEntity.DeEntitize (parte di HTML Agility Pack). Ciò è necessario per elaborare manualmente le entità in alcuni casi.
Matthew Flaschen,

1
nota: nell'ultima beta di Html Agility Pack (1.4.0 Beta 2 rilasciata il 3 ottobre 2009) il file della guida è stato spostato in un download separato a causa delle dipendenze da Sandcastle, DocProject e Visual Studio 2008 SDK.
rtpHarry,

SelectSingleNode() sembra essere stato rimosso un po 'di tempo fa
Chris S il

3
No, SelectSingleNode e SelectNodes sono sicuramente ancora lì. Trovo un po 'interessante che dovrebbe essere htmlDoc.ParseErrors.Count (), non .Count
Mike Blandford,

1
@MikeBlandford // Parzialmente sì. Sembra essere rimosso (o non esistito dall'inizio) nella versione PCL di HtmlAgailityPack. nuget.org/packages/HtmlAgilityPack-PCL
Joon Hong

166

Non so se questo ti sarà di aiuto, ma ho scritto un paio di articoli che introducono le basi.

Il prossimo articolo è completo al 95%, devo solo scrivere spiegazioni delle ultime parti del codice che ho scritto. Se sei interessato, cercherò di ricordare di postare qui quando lo pubblicherò.



3
Recentemente in Code Project è stato rilasciato un ottimo articolo di HTMLAgilityPack. Puoi leggerlo qui
Victor Sigler,

64

HtmlAgilityPack utilizza la sintassi XPath e sebbene molti sostengano che sia scarsamente documentato, non ho avuto problemi a usarlo con l'aiuto di questa documentazione XPath: https://www.w3schools.com/xml/xpath_syntax.asp

Analizzare

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

L'ho fatto:

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 vero. Dipende completamente dallo XPathstandard. Uno dovrebbe prima imparare quello standard e tutto sarà facile dopo.
FindOut_Quran,

Il link che hai fornito non è più disponibile. Questo è probabilmente il nuovo: w3schools.com/xsl/xpath_syntax.asp
Piotrek,

inoltre non riesco a vedere alcuna funzione SelectNodes () nell'oggetto DocumentNode. È stato rinominato?
Piotrek,

Quale versione stai usando e da dove l'hai scaricata? Secondo htmlagilitypack.codeplex.com/SourceControl/latest#Release/1_4_0/… dovrebbe esserci un metodo SelectNodes sulla classe HtmlNode.
Kent Munthe Caspersen,

Link non disponibile, nuovo link: www.w3schools.com/xml/xpath_syntax.asp
Tyrmos

6

Il codice principale di HTMLAgilityPack è il seguente

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
Il sito web non è più disponibile
Dimitar Tsonev il

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

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

prova questo

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;
        }
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.