Comment utiliser le pack HTML Agility

629

Comment utiliser le pack d'agilité HTML ?

Mon document XHTML n'est pas complètement valide. Voilà pourquoi je voulais l'utiliser. Comment l'utiliser dans mon projet? Mon projet est en C #.

carla
la source
79
Cette question m'a été très utile.
BigJoe714
26
Note latérale: avec un Visual Studio qui gère NuGet, vous pouvez maintenant cliquer avec le bouton droit sur "Références" et choisir "Gérer les packages NuGet ...", rechercher "HtmlAgilityPack" et cliquer sur "Installer". Ensuite, commencez à jouer avec le code avec une instruction using / Import.
patridge
Concernant le commentaire ci-dessus de @patridge: J'ai trouvé que j'avais besoin de supprimer puis de rajouter ma référence au HtmlAgilityPack lors de la première extraction du projet depuis svn via ankhsvn.
Andrew Coonce
14
Quiconque cherche dans HTMLAgilityPack devrait considérer CsQuery, c'est une bibliothèque beaucoup plus récente avec une interface beaucoup plus moderne d'après mon expérience. Par exemple, le code entier de la première réponse peut être résumé dans CsQuery comme var body = CQ.CreateFromFile(filePath)["body"].
Benjamin Gruenbaum
2
@BenjaminGruenbaum: Bravo pour votre suggestion CsQuery - mise en place en quelques minutes, très facile à utiliser.
Neolisk

Réponses:

358

Tout d'abord, installez le package de nuget HTMLAgilityPack dans votre projet.

Ensuite, à titre d'exemple:

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: Ce code n'est qu'un exemple et pas nécessairement la meilleure / seule approche. Ne l'utilisez pas aveuglément dans votre propre application.)

La HtmlDocument.Load()méthode accepte également un flux qui est très utile pour l'intégration avec d'autres classes orientées flux dans le framework .NET. Tandis queHtmlEntity.DeEntitize() est une autre méthode utile pour traiter correctement les entités html. (merci Matthew)

HtmlDocument et HtmlNode sont les classes que vous utiliserez le plus. Semblable à un analyseur XML, il fournit les méthodes selectSingleNode et selectNodes qui acceptent les expressions XPath.

Faites attention aux HtmlDocument.Option?????? propriétés booléennes. Ceux-ci contrôlent laLoadLoadXML méthodes et traiteront votre code HTML / XHTML.

Il existe également un fichier d'aide compilé appelé HtmlAgilityPack.chm qui contient une référence complète pour chacun des objets. Il se trouve normalement dans le dossier de base de la solution.

Cendre
la source
11
Notez également que Load accepte un paramètre Stream, ce qui est pratique dans de nombreuses situations. Je l'ai utilisé pour un flux HTTP (WebResponse.GetResponseStream). Une autre bonne méthode à connaître est HtmlEntity.DeEntitize (qui fait partie de HTML Agility Pack). Cela est nécessaire pour traiter les entités manuellement dans certains cas.
Matthew Flaschen
1
Remarque: dans la dernière version bêta de Html Agility Pack (1.4.0 Beta 2 publiée le 3 octobre 2009), le fichier d'aide a été déplacé dans un téléchargement distinct en raison des dépendances de Sandcastle, DocProject et du SDK Visual Studio 2008.
rtpHarry
SelectSingleNode() semble avoir été supprimé il y a quelque temps
Chris S
3
Non, SelectSingleNode et SelectNodes sont définitivement toujours là. Je trouve un peu intéressant que ce soit htmlDoc.ParseErrors.Count (), pas .Count
Mike Blandford
1
@MikeBlandford // Partiellement oui. Il semble avoir été supprimé (ou inexistant depuis le début) dans la version PCL de HtmlAgailityPack. nuget.org/packages/HtmlAgilityPack-PCL
Joon Hong
166

Je ne sais pas si cela vous sera utile, mais j'ai écrit quelques articles qui présentent les bases.

Le prochain article est terminé à 95%, il me suffit de rédiger des explications sur les dernières parties du code que j'ai écrites. Si vous êtes intéressé, je vais essayer de ne pas oublier de poster ici lorsque je le publierai.

rtpHarry
la source
3
Récemment, dans Code Project, il a été publié un très bon article de HTMLAgilityPack. Vous pouvez le lire ici
Victor Sigler
64

HtmlAgilityPack utilise la syntaxe XPath, et bien que beaucoup soutiennent qu'elle est mal documentée, je n'ai eu aucun problème à l'utiliser avec l'aide de cette documentation XPath: https://www.w3schools.com/xml/xpath_syntax.asp

Analyser

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

J'ai fait ça:

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
la source
Totalement vrai. Il dépend entièrement de la XPathnorme. Il faut d'abord apprendre ce standard et tout sera facile après cela.
FindOut_Quran
Le lien que vous avez fourni n'est plus disponible. C'est probablement le nouveau: w3schools.com/xsl/xpath_syntax.asp
Piotrek
Je ne vois pas non plus de fonction SelectNodes () dans l'objet DocumentNode. Est-il renommé?
Piotrek
Quelle version utilisez-vous et d'où l'avez-vous téléchargée? Selon htmlagilitypack.codeplex.com/SourceControl/latest#Release/1_4_0/…, il devrait y avoir une méthode SelectNodes sur la classe HtmlNode.
Kent Munthe Caspersen
Lien non disponible, nouveau lien: www.w3schools.com/xml/xpath_syntax.asp
Tyrmos
6

Le code principal lié à HTMLAgilityPack est le suivant

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
la source
4
Le site n'est plus disponible
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
la source
0

Mise en route - 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
la source
0

essaye ça

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