Ottieni solo il testo di una pagina Web utilizzando HTML Agility Pack?

c# html-agility-pack

Domanda

Sto cercando di raschiare una pagina web per ottenere solo il testo. Sto mettendo ogni parola in un dizionario e contando quante volte ogni parola appare sulla pagina. Sto cercando di utilizzare HTML Agility Pack come suggerito da questo post: Come ottenere il numero di parole su una pagina 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
    }
}

Tuttavia, con la mia attuale implementazione, sto ancora ricevendo molti risultati dal markup che non dovrebbero essere contati. È vicino, ma non ancora del tutto (non mi aspetto che sia perfetto).

Sto usando questa pagina come esempio. I miei risultati mostrano molti degli usi delle parole "larghezza" e "googletag", nonostante quelli che non si trovano nel vero testo della pagina.

Qualche suggerimento su come risolvere questo problema? Grazie!

Risposta popolare

Non puoi essere sicuro che la parola che stai cercando sia visualizzata o meno all'utente poiché ci saranno esecuzioni JS e regole CSS che lo influenzeranno.

Il seguente programma trova 0 corrispondenze per "larghezza" e "googletag" ma trova 126 corrispondenze "html" mentre Chrome Ctrl + F trova 106 corrispondenze.

Si noti che il programma non corrisponde alla parola se il nodo genitore è <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();
            }
        }
    }
}


Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché