Obtenir uniquement le texte d'une page Web utilisant HTML Agility Pack?

c# html-agility-pack

Question

J'essaie de gratter une page Web pour obtenir uniquement le texte. Je mets chaque mot dans un dictionnaire et compte combien de fois chaque mot apparaît sur la page. J'essaie d'utiliser HTML Agility Pack comme suggéré dans cet article: Comment obtenir le nombre de mots sur une page Web?

HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(url);
int wordCount = 0;
Dictionary<string, int> dict = new Dictionary<string, int>();

foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//text()"))
{
    MatchCollection matches = Regex.Matches(node.InnerText, @"\b(?:[a-z]{2,}|[ai])\b", RegexOptions.IgnoreCase);
    foreach (Match s in matches)
    {
       //Add the entry to the dictionary
    }
}

Cependant, avec ma mise en œuvre actuelle, je reçois toujours de nombreux résultats du balisage qui ne doivent pas être comptés. C'est proche, mais pas encore là (je ne m'attends pas à ce que ce soit parfait).

J'utilise cette page à titre d'exemple. Mes résultats montrent de nombreuses utilisations des mots "width" et "googletag", même si ceux-ci ne figurent pas dans le texte de la page.

Des suggestions sur la façon de résoudre ce problème? Merci!

Réponse populaire

Vous ne pouvez pas être sûr que le mot que vous recherchez soit affiché ou non pour l'utilisateur car il y aura des règles d'exécution JS et CSS qui affecteront cela.

Le programme suivant trouve 0 correspondances pour "width" et "googletag" mais trouve 126 correspondances "html" alors que Chrome Ctrl + F trouve 106 correspondances.

Notez que le programme ne correspond pas au mot si son noeud parent est <script> .

using HtmlAgilityPack;
using System;

namespace WordCounter
{
    class Program
    {
        private static readonly Uri Uri = new Uri("https://www.w3schools.com/html/html_editors.asp");

        static void Main(string[] args)
        {
            var doc = new HtmlWeb().Load(Uri);
            var nodes = doc.DocumentNode.SelectSingleNode("//body").DescendantsAndSelf();
            var word = Console.ReadLine().ToLower();
            while (word != "exit")
            {
                var count = 0;
                foreach (var node in nodes)
                {
                    if (node.NodeType == HtmlNodeType.Text && node.ParentNode.Name != "script" && node.InnerText.ToLower().Contains(word))
                    {
                        count++;
                    }
                }

                Console.WriteLine($"{word} is displayed {count} times.");
                word = Console.ReadLine().ToLower();
            }
        }
    }
}


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi