【问题标题】:HtmlAgilityPack SelectNodes, DisposingHtmlAgilityPack SelectNodes,处理
【发布时间】:2013-02-23 23:31:39
【问题描述】:

我正在尝试使用 SelectNodes 使用 HtmlAgilityPack 进行一些屏幕抓取,并从返回的每个节点获取一些值

这里是代码

private readonly HtmlDocument _document = new HtmlDocument();

public void ParseValues(string html)
{
    _document.LoadHtml(html);
    var tables = _document.DocumentNode.SelectNodes("//table");

    foreach (var table in tables)
    {
        _document.LoadHtml(table.OuterHtml);
        var value = _document.DocumentNode.SelectSingleNode("//tbody[1]/tr/td[0]");
    }
}

但我注意到,当尝试在 foreach 循环内选择子项时,它实际上是从文档根目录中搜索的。真的很烦人。

问题:

  1. 有没有办法从SelectNodes 返回的每个表中选择值,而不必从HtmlDocument 创建新的文档实例?

  2. 有没有办法处置HtmlDocument,因为我注意到每次使用_document.LoadHtml(html)都会出现内存泄漏;

【问题讨论】:

    标签: c# web-scraping html-agility-pack


    【解决方案1】:

    (更详细的解释见Html Agility Pack - Problem selecting subnode


    不必创建另一个 HtmlDocument 对象,或将另一个 HTML 加载到其中。你只需要这样做:

    foreach (var table in tables)
    {
        var value = table.SelectSingleNode(".//tbody[1]/tr/td[0]");
    }
    

    关键是使用.//tbody 而不是//tbody

    【讨论】:

    • 那么如何处理 HtmlDocument 呢?
    • 如果我没有创建 HtmlDocument 的新实例,我也会收到此错误。 startIndex 不能大于字符串的长度。
    • 我只是回答你的第一个问题。
    • 我不明白...如果您使用我的foreach 而不是您的,是否会出现该错误?
    • 请把你正在解析的HTML分享一下,我可以在这里调试,给你一个更详细的答案。您可以使用pastebin 或类似服务。
    猜你喜欢
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 2011-12-14
    • 2014-05-29
    • 1970-01-01
    相关资源
    最近更新 更多