【问题标题】:Why is my Foreach only outputting the first bit of data?为什么我的 Foreach 只输出第一位数据?
【发布时间】:2019-03-14 18:56:30
【问题描述】:

对机器人和 C# 来说一般来说是新的。我正在尝试输出与//a[@class='featuredBox 匹配的所有链接内部文本,但它只输出数据的第一位。

当我调试时,它确实附加了很多值,所以我很困惑为什么这没有全部输出?

    protected void Page_Load(object sender, EventArgs e)
{
    HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = web.Load("https://www.jasminedirectory.com/computers/companies/");

    var headingNames = doc.DocumentNode.SelectNodes("//a[@class='featuredBox']").ToList();

    foreach (var item in headingNames)
    {
        botOutput.Text = item.InnerText + "</br>";
    }
}

任何帮助将不胜感激。

【问题讨论】:

  • headingNames中是否有多个项目?
  • 是的,有。不少。
  • 或者你可以用 Linq 代替 foreach 循环:botOutput.Text = string.Join("&lt;/br&gt;", headingNames.Select(item =&gt; item.InnerText)) + "&lt;/br&gt;";

标签: c# web-scraping foreach


【解决方案1】:

尝试在= 之前添加+。目前看起来你只是在每个循环上覆盖Text 属性,听起来你想追加每个匹配项。

protected void Page_Load(object sender, EventArgs e)
{
  HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
  HtmlAgilityPack.HtmlDocument doc = web.Load("https://www.jasminedirectory.com/computers/companies/");

  var headingNames = doc.DocumentNode.SelectNodes("//a[@class='featuredBox']").ToList();

  foreach (var item in headingNames)
  {
    botOutput.Text += item.InnerText + "</br>";
  }
}

替代方法:

protected void Page_Load(object sender, EventArgs e)
{
  HtmlAgilityPack.HtmlWeb web = new HtmlAgilityPack.HtmlWeb();
  HtmlAgilityPack.HtmlDocument doc = web.Load("https://www.jasminedirectory.com/computers/companies/");

  var headingNames = doc.DocumentNode.SelectNodes("//a[@class='featuredBox']").ToList();
  botOutput = headingNames.Select(name => name.InnerText).Aggregate((current, next) => $"{current}</br>{next}") + "</br>";
}

【讨论】:

  • 奇怪的是,它只是显示的“第一个”条目,而不是最后一个。通常,当这种情况发生时,您只会看到最后一项。
  • 啊!这样就解决了问题。对自己非常沮丧,因为我前几天才知道。谢谢!
  • @gunr2171 同意,但这似乎还是可能的
  • 很高兴听到这个消息,@GerryHodson!
  • 正如@zero 所指出的,您可能希望使用 StringBuilder 来构建字符串,然后将其分配给文本框的文本。在循环中进行字符串连接几乎总是一个坏主意。
【解决方案2】:

你不断地替换(而不是追加)。改为这样做:

foreach (var item in headingNames)
{
    botOutput.Text += item.InnerText + "</br>";
}

可能值得注意的是,如果headingNames 很大,您应该使用StringBuilder,否则您会产生不必要的GC 压力,因为string 是不可变的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-13
    • 1970-01-01
    • 2021-12-11
    • 2012-02-18
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多