只使用HTML Agility Pack獲取網頁文本?

c# html-agility-pack

我正在嘗試抓取一個網頁來獲取文本。我將每個單詞放入字典中,併計算每個單詞出現在頁面上的次數。我正在嘗試使用HTML Agility Pack,如本文所示: 如何獲取網頁上的單詞數量?

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

但是,根據我目前的實現,我仍然會從標記中獲得大量不應計算的結果。它很接近,但還不是很完美(我不認為它是完美的)。

我正在使用此頁面作為示例。我的結果顯示了“width”和“googletag”這兩個詞的大量用法,儘管這些內容根本不在頁面的實際文本中。

對於如何解決這個問題,有任何的建議嗎?謝謝!

熱門答案

您無法確定是否向用戶顯示您要搜索的單詞,因為將會有JS執行和CSS規則影響該單詞。

以下程序找到0個匹配“width”和“googletag”,但找到126個“html”匹配,而Chrome Ctrl + F找到106個匹配。

請注意,如果該節點的父節點是<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();
            }
        }
    }
}


許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因