¿Obtener solo el texto de una página web usando HTML Agility Pack?

c# html-agility-pack

Pregunta

Estoy tratando de raspar una página web para obtener sólo el texto. Pongo cada palabra en un diccionario y cuento cuántas veces aparece cada palabra en la página. Estoy tratando de usar HTML Agility Pack como se sugiere en esta publicación: ¿Cómo obtener el número de palabras en una página 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
    }
}

Sin embargo, con mi implementación actual, todavía estoy obteniendo muchos resultados del marcado que no se deben contar. Está cerca, pero todavía no está del todo allí (no espero que sea perfecto).

Estoy usando esta página como ejemplo. Mis resultados muestran muchos de los usos de las palabras "ancho" y "googletag", a pesar de que no están en absoluto en el texto real de la página.

Alguna sugerencia en como arreglar esto? ¡Gracias!

Respuesta popular

No puede estar seguro de que la palabra que está buscando se muestre o no al usuario ya que habrá ejecución de JS y reglas de CSS que afectarán eso.

El siguiente programa encuentra 0 coincidencias para "ancho" y "googletag" pero encuentra 126 coincidencias "html" mientras que Chrome Ctrl + F encuentra 106 coincidencias.

Tenga en cuenta que el programa no coincide con la palabra si su nodo principal es <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();
            }
        }
    }
}


Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué