Verwendung des HTML Agility Packs


629

Wie verwende ich das HTML Agility Pack ?

Mein XHTML-Dokument ist nicht vollständig gültig. Deshalb wollte ich es benutzen. Wie verwende ich es in meinem Projekt? Mein Projekt ist in C #.


79
Diese Frage war sehr hilfreich für mich.
BigJoe714

26
Randnotiz: Mit einem Visual Studio, das NuGet verarbeitet, können Sie jetzt mit der rechten Maustaste auf "Referenzen" klicken und "NuGet-Pakete verwalten ..." auswählen, nach "HtmlAgilityPack" suchen und auf "Installieren" klicken. Spielen Sie dann gleich mit dem Code mit einer using / Import-Anweisung.
Patridge

In Bezug auf den obigen Kommentar von @patridge: Ich stellte fest, dass ich meinen Verweis auf das HtmlAgilityPack entfernen und dann wieder hinzufügen musste, wenn ich das Projekt zum ersten Mal von svn über ankhsvn abrief.
Andrew Coonce

14
Jeder, der sich mit HTMLAgilityPack befasst, sollte CsQuery in Betracht ziehen. Es ist eine viel neuere Bibliothek mit einer meiner Erfahrung nach viel moderneren Oberfläche. Beispielsweise kann der gesamte Code aus der ersten Antwort in CsQuery als zusammengefasst werden var body = CQ.CreateFromFile(filePath)["body"].
Benjamin Gruenbaum

2
@BenjaminGruenbaum: Daumen hoch für Ihren CsQuery-Vorschlag - in wenigen Minuten eingerichtet, sehr einfach zu bedienen.
Neolisk

Antworten:


358

Installieren Sie zunächst das HTMLAgilityPack- Nuget-Paket in Ihrem Projekt.

Dann als Beispiel:

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

(Hinweis: Dieser Code ist nur ein Beispiel und nicht unbedingt der beste / einzige Ansatz. Verwenden Sie ihn nicht blind in Ihrer eigenen Anwendung.)

Die HtmlDocument.Load()Methode akzeptiert auch einen Stream, der bei der Integration in andere streamorientierte Klassen in .NET Framework sehr nützlich ist. While HtmlEntity.DeEntitize()ist eine weitere nützliche Methode zur korrekten Verarbeitung von HTML-Entitäten. (Danke Matthew)

HtmlDocumentund HtmlNode sind die Klassen, die Sie am meisten verwenden werden. Ähnlich wie bei einem XML-Parser werden die Methoden selectSingleNode und selectNodes bereitgestellt, die XPath-Ausdrücke akzeptieren.

Achten Sie auf die HtmlDocument.Option?????? booleschen Eigenschaften. Diese Kontrolle , wie die Loadund LoadXMLMethoden verarbeiten Ihre HTML / XHTML.

Es gibt auch eine kompilierte Hilfedatei namens HtmlAgilityPack.chm, die eine vollständige Referenz für jedes der Objekte enthält. Dies befindet sich normalerweise im Basisordner der Lösung.


11
Beachten Sie auch, dass Load einen Stream-Parameter akzeptiert, was in vielen Situationen praktisch ist. Ich habe es für einen HTTP-Stream (WebResponse.GetResponseStream) verwendet. Eine weitere gute Methode ist HtmlEntity.DeEntitize (Teil des HTML Agility Pack). Dies ist in einigen Fällen erforderlich, um Entitäten manuell zu verarbeiten.
Matthew Flaschen

1
Hinweis: In der neuesten Beta von Html Agility Pack (1.4.0 Beta 2, veröffentlicht am 3. Oktober 2009) wurde die Hilfedatei aufgrund von Abhängigkeiten von Sandcastle, DocProject und dem Visual Studio 2008 SDK in einen separaten Download verschoben.
RTPHarry

SelectSingleNode() scheint vor einiger Zeit entfernt worden zu sein
Chris S

3
Nein, SelectSingleNode und SelectNodes sind definitiv noch da. Ich finde es ein wenig interessant, dass es htmlDoc.ParseErrors.Count () sein sollte, nicht .Count
Mike Blandford

1
@ MikeBlandford // Teilweise ja. Es scheint in der PCL-Version von HtmlAgailityPack entfernt worden zu sein (oder von Anfang an nicht vorhanden zu sein). nuget.org/packages/HtmlAgilityPack-PCL
Joon Hong

166

Ich weiß nicht, ob dies für Sie hilfreich sein wird, aber ich habe einige Artikel geschrieben, in denen die Grundlagen vorgestellt werden.

Der nächste Artikel ist zu 95% vollständig. Ich muss nur Erklärungen zu den letzten Teilen des Codes schreiben, den ich geschrieben habe. Wenn Sie interessiert sind, werde ich versuchen, mich daran zu erinnern, hier zu posten, wenn ich es veröffentliche.



3
Kürzlich wurde in Code Project ein sehr guter Artikel von HTMLAgilityPack veröffentlicht. Sie können es hier
Victor Sigler

64

HtmlAgilityPack verwendet die XPath-Syntax, und obwohl viele argumentieren, dass sie schlecht dokumentiert ist, hatte ich keine Probleme, sie mithilfe dieser XPath-Dokumentation zu verwenden: https://www.w3schools.com/xml/xpath_syntax.asp

Zu analysieren

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

Ich war das:

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

Völlig wahr. Es ist voll vom XPathStandard abhängig . Man sollte zuerst diesen Standard lernen und danach wird alles einfach.
FindOut_Quran

Der von Ihnen angegebene Link ist nicht mehr verfügbar. Dies ist wahrscheinlich die neue: w3schools.com/xsl/xpath_syntax.asp
Piotrek

Außerdem kann ich keine SelectNodes () -Funktion im DocumentNode-Objekt sehen. Wird es umbenannt?
Piotrek

Welche Version verwenden Sie und von wo haben Sie sie heruntergeladen? Laut htmlagilitypack.codeplex.com/SourceControl/latest#Release/1_4_0/… sollte es eine SelectNodes-Methode für die HtmlNode-Klasse geben.
Kent Munthe Caspersen

Link nicht verfügbar, neuer Link: www.w3schools.com/xml/xpath_syntax.asp
Tyrmos

6

Der Hauptcode für HTMLAgilityPack lautet wie folgt

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
Die Website ist nicht mehr verfügbar
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

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

Versuche dies

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;
        }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.