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

Carla
quelle
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.

Asche
quelle
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.

rtpHarry
quelle
16
Endlich fertig mit diesem Artikel zwei Jahre später :) Eine einfache Methode zum Erkennen von RSS- und Atom-Feeds auf Websites mit HtmlAgilityPack
rtpHarry
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);
}
Kent Munthe Caspersen
quelle
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;
        }
    }
}
Captainsac
quelle
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";
        }

    }
ibrahim ozboluk
quelle
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);
Meysam
quelle
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;
        }
PK-1825
quelle