【问题标题】:Scraping product page with HttpAgilityPack - Not getting all products使用 HttpAgilityPack 抓取产品页面 - 未获取所有产品
【发布时间】:2016-03-16 10:58:57
【问题描述】:

上下文:

我正在用 C# 开发一个桌面应用程序,用于从少数域中的单个网页中抓取/分析产品信息。我使用 HtmlAgilityPack 来捕获和解析页面以获取所需的数据。我为不同的域编写不同的解析规则。

问题:

来自一个特定域的页面,当通过浏览器显示时,可能会显示 60-80 种产品。但是,当我通过 HtmlAgilityPack 解析时,最多只能获得 20 个产品。查看 Firefox“查看页面源代码”中的原始 html,似乎也只有 20 个相关产品 div 存在。我得出的结论是,必须通过脚本加载剩余的产品,也许是为了减轻服务器上的负载。事实上,我有时会在浏览器中看到这种情况,因为在加载 20 多个产品时会出现短暂的暂停,然后再加载 20 个,等等。

问题:

如何通过 HtmlAgilityPack 或其他方式访问所有脚本编写完成后出现的全套产品 div?

【问题讨论】:

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


    【解决方案1】:

    您可以使用System.Windows.Forms 中的WebBrowser 来加载数据,并使用敏捷包来解析它。它看起来像这样:

     var browser = new WebBrowser();
     browser.Navigate("http://whatever.com");
    
      while (true)
      {
          if(browser.ReadyState == WebBrowserReadyState.Complete && browser.IsBusy != true)
          {
            break;
          }
            //not for production
            Thread.Sleep(1000)
      }
    
    
      var doc = new HtmlAgilityPack.HtmlDocument();
      var dom = (IHTMLDocument3)browser.Document.DomDocument; 
      StringReader reader = new StringReader(dom.documentElement.outerHTML); 
      doc.Load(reader);
    

    查看here了解更多详情

    【讨论】:

    • 谢谢@swestner - 看起来很有希望。不幸的是,我正在做一个 WPF 应用程序,因此 System.Windows.Forms 不能立即提供给我,但我怀疑有一个解决方法可以解决这个问题。与此同时,我正在使用我刚刚发现的 Selenium 包将类似的东西组合在一起。我将在下面发布结果。
    【解决方案2】:

    好的,我已经使用 Selenium 包(可通过 NuGet 获得)进行了一些工作。代码如下所示:

        private HtmlDocument FetchPageWithSelenium(string url)
        {
            IWebDriver driver = new FirefoxDriver();
            IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
    
            driver.Navigate().GoToUrl(url);
    
           // Scroll to the bottom of the page and pause for more products to load.
           // Do it four times as there may be 4x20 products to retrieve.
            js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
            Thread.Sleep(2000);
            js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
            Thread.Sleep(2000);
            js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
            Thread.Sleep(2000);
            js.ExecuteScript("window.scrollTo(0, document.body.scrollHeight);");
    
            HtmlDocument webPage = new HtmlDocument();
            webPage.LoadHtml(driver.PageSource.ToString());
    
            driver.Quit();
    
            return webPage;
        }
    

    这将返回一个 HtmlAgilityPack HtmlDocument 以供进一步分析,首先通过反复滚动到底部强制页面完全加载。两个问题悬而未决:

    1. 代码启动 Firefox,然后在完成后再次停止。这有点笨拙,我宁愿这一切都在不可见的情况下发生。建议您可以通过使用 PhantomJS 驱动程序而不是 Firefox 驱动程序来避免这种情况。这并没有帮助,因为它只是弹出一个 Windows 控制台窗口。
    2. 由于在脚本加载补充内容时加载浏览器和暂停所花费的时间,它有点慢。不过我大概可以忍受。

    我将尝试重新编写 @swestner 代码以使其在 WPF 应用程序中运行,看看哪个是更整洁的解决方案。

    【讨论】:

      猜你喜欢
      • 2019-11-07
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 2020-09-28
      • 2012-02-11
      相关资源
      最近更新 更多