【问题标题】:How to get only human-visible text from page C# with HTMLAgilityPack?如何使用 HTMLAgilityPack 从 C# 页面仅获取人类可见的文本?
【发布时间】:2022-11-23 02:11:20
【问题描述】:

我试图从页面中仅获取可见文本,将其拆分并返回页面上的单词数组。 我的代码:

public async Task<string[]> GetText(string link)
{
    string htmlSource = await httpClient.GetStringAsync(link);
    string text = "";
    page = new HtmlDocument();
    page.LoadHtml(htmlSource);
    IEnumerable<HtmlNode> nodes = page.DocumentNode.Descendants().Where(n =>
        n.NodeType == HtmlNodeType.Text &&
        n.ParentNode.Name != "script" &&
        n.ParentNode.Name != "style");
    foreach (HtmlNode node in nodes)
    {
        text += node.InnerText;
    }
    Regex regex = new Regex(@"\W");
    text = text.ToLower();
    text = regex.Replace(text, " ");
    string[] result = text.Split(' ');

    return result;
}

我的代码使它不好,因为它合并了单词 我认为问题是我如何从节点中提取文本,但我不知道如何修复它

【问题讨论】:

  • 只是在每个节点的末尾添加一个空格?所以在foreach循环中:text += node.InnerText + " ";
  • 所以隐藏的 div 中的文本不好吗?
  • 请澄清“可见”。人类可见的内容可能与 HTML 源代码中的内容完全不同。

标签: c# html-agility-pack


【解决方案1】:

返回一个列表而不是一个数组。这使您可以在几个地方简化代码:

public async Task<List<string>> GetText(string link)
{
    string htmlSource = await httpClient.GetStringAsync(link);
    var result = new List<string>();
    page = new HtmlDocument();
    page.LoadHtml(htmlSource);
    var results = page.DocumentNode.Descendants().
        Where(n =>
            n.NodeType == HtmlNodeType.Text &&
            n.ParentNode.Name != "script" &&
            n.ParentNode.Name != "style"
        ).Select(n => n.InnerText.ToLower());

    return results.ToList();
}

在 async/await 出现之前,我会提倡使用 IEnumerable,但是这里的异步故事还没有那么好(即:下面的代码不会按预期工作)并且 IAsyncEnumerable 有一些粗糙的边缘:

public async Task<IEnumerable<string>> GetText(string link)
{
    string htmlSource = await httpClient.GetStringAsync(link);
    page = new HtmlDocument();
    page.LoadHtml(htmlSource);

    return page.DocumentNode.Descendants().
        Where(n =>
            n.NodeType == HtmlNodeType.Text &&
            n.ParentNode.Name != "script" &&
            n.ParentNode.Name != "style"
        ).Select(n => n.InnerText.ToLower());
}

但我仍然认为值得关注这一点。当异步世界还学习如何避免需要将整个集合加载到内存中时,还有另一个重要的性能水平。

【讨论】:

    猜你喜欢
    • 2013-10-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-19
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多