C# HtmlNode 解析抛出 Collection was modified 错误

C# HtmlNode parsing throws Collection was modified error

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

System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute.'

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

    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,我不是。

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

    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();