【问题标题】:C# HtmlNode parsing throws Collection was modified errorC# HtmlNode 解析抛出 Collection was modified 错误
【发布时间】:2019-12-28 22:13:09
【问题描述】:

这对我来说有点奇怪。我有一个HtmlDocument,在解析时我得到:

System.InvalidOperationException: '集合已修改;枚举操作可能无法执行。'

让我感到奇怪的是,我没有遍历从我的代码返回的列表,我仍然收到此错误。

    using (HttpClient client = new HttpClient())
        {
             using (HttpResponseMessage response = await client.GetAsync(url))
             {
                  response.EnsureSuccessStatusCode(); // Throw if httpcode is an error
                  using (HttpContent content = response.Content)
                       {
                             string result = await content.ReadAsStringAsync();
                             var website = new HtmlDocument();
                             website.LoadHtml(result);
                             //Thread.Sleep(5000);
                             List<HtmlNode>topbar = website.DocumentNode.Descendants("div").FirstOrDefault(o => o.GetAttributeValue("class", "") == "valueofClass")
                                 .Descendants("div").FirstOrDefault(o => o.GetAttributeValue("class", "") == "valueofClass").Elements("section").ToList();
                             //loop
                       }
            }
      }

如果我添加一个Sleep 代码似乎可以正常工作,这让我认为LoadHtml 仍在后台工作,或者我正在执行某种javascript,但我不是。

【问题讨论】:

    标签: list http parsing collections html-agility-pack


    【解决方案1】:

    您是否尝试过以下方法来获取HtmlNodeCollection,方法是使用SelectNodes,而不是在查询后运行Descendants 两次以获取单个节点。

        using (HttpContent content = response.Content)
                {
                    string result = await content.ReadAsStringAsync();
                    var website = new HtmlDocument();
                    website.LoadHtml(result);
    
                    HtmlNodeCollection topbar = website.DocumentNode.SelectNodes("//div[@class='valueofClass']//section");
    
                    if (topbar != null)
                        foreach (HtmlNode node in topbar) 
                        {
                            ....
                        }
                }
    
    

    topbar 包含所有可能的节点列表,这些节点是 div,类名称为 valueofClass,包含标签 section,我假设您正在尝试使用 Descendants 和 FirstOrDefault 查找.

    我看到的另一件事是,在您的 FirstOrDefault 语句中,您使用 == 比较字符串。如果您想使用 Descendants 路线,我建议使用 .Equals() 正确比较两个字符串。如果您的比较在第一个 FirstOrDefault 语句中给出一个空值,那么第二个 Descendants 将与 Object reference not set to instance of an object. 一起失败

    更新:

    如果您想对多个后代使用该语句,我建议使用ToList() 转换后代的IEnumerable 结果,然后使用 FirstOrDefault() 对其进行过滤。这将有助于解决您遇到的错误。

      website.DocumentNode
        .Descendants("div").ToList()
            .FirstOrDefault(o => o.GetAttributeValue("class", "") == "valueofClass")
        .Descendants("div").ToList()
            .FirstOrDefault(o => o.GetAttributeValue("class", "") == "valueofClass")
        .Elements("section").ToList();
    

    【讨论】:

    • 据我了解,这只是解析的另一种写法。稍后我会试一试,因为我现在不在,看看效果如何。
    猜你喜欢
    • 2012-07-02
    • 1970-01-01
    • 2017-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-27
    相关资源
    最近更新 更多