【问题标题】:How can I scrape data from a Webpage after searching desired data using HTML Agility使用 HTML Agility 搜索所需数据后,如何从网页中抓取数据
【发布时间】:2018-04-27 16:12:45
【问题描述】:

我想从this website获取信息

使用 HTML Agility Pack 进入我的 ASPX 页面。但我不能这样做,因为数据是在我搜索网页中的数据后加载的。

我需要在 5 分钟间隔后连续完成一些数据。

【问题讨论】:

    标签: c# html asp.net html-agility-pack


    【解决方案1】:

    您提到的网站中的搜索结果是使用 Javascript 动态呈现的,并且数据通过 Ajax 以 Json 响应的形式出现。 HtmlAgilityPack 旨在解析 Html,而不是 Json。

    考虑为 .Net 使用 SeleniumiMacros 驱动程序,或使用 Microsoft Framework 提供的 WebBrowser 类。这些工具在后台运行浏览器,因此它们可以在该页面中运行 Javascript 代码并呈现您想要抓取的 Html。

    只需要设置适当的超时时间,这样他们就会一直等到搜索结果出现在页面上。

    【讨论】:

      【解决方案2】:

      正如@derloopkat 已经说过的那样。只需使用 Selenium。

      该站点使用 javascript 和 ajax 来更新页面的 HTML。即使您使用以下 url 发出 HTTP 请求:

      https://enquiry.indianrail.gov.in/ntes/NTES?action=getTrainsViaStn&viaStn=NDLS&toStn=null&withinHrs=2&trainType=ALL&6iop0ssrpi=1m1ol4ha86
      

      您只会得到以下内容:

      (function(){location.reload();/*ho ho ho ho*/})()
      

      表示url的最后一个参数:

      &6iop0ssrpi=1m1ol4ha86
      

      是某种“密码”(因为没有更好的词)。这确保您不能只重播请求。现在你可以尝试破解它。但是它在一个 3396 行非常密集的代码的 javascript 文件中被隐藏了。所以很难(甚至不可能)找出向服务器发送什么来接收你想要的数据。

      更好的是,来自服务器的响应永远不会是 HTML,而是 JSON。格式如下:

          _obj_1511003507337 = {
      trainsInStnDataFound:"trainRunningDataFound",
      allTrains:[
      {
      trainNo:"14316",
      startDate:"18 Nov 2017",
      trainName:"INTERCITY EXP",
      trnName:function(){return _LANG==="en-us"?"INTERCITY EXP":"इंटरसिटीएक्स."},
      trainSrc:"NDLS",
      trainDstn:"BE",
      runsOn:"NA",
      schArr:"Source",
      schDep:"16:35, 18 Nov",
      schHalt:"Source",
      actArr:"Source",
      delayArr:"RIGHT TIME",
      actDep:"16:35, 18 Nov",
      delayDep:"RIGHT TIME",
      actHalt:"Source",
      trainType:"MEX",
      pfNo:"9"
      } ,
      trainNo:"12625",
      startDate:"16 Nov 2017",
      trainName:"KERALA EXPRESS",
      trnName:function() { return _LANG === "en-us" ? "KERALA EXPRESS" : "केरलएक्स."},
      trainSrc:"TVC",
      trainDstn:"NDLS",
      runsOn:"NA",
      schArr:"13:45, 18 Nov",
      schDep:"Destination",
      schHalt:"Destination",
      actArr:"16:56, 18 Nov",
      delayArr:"03:11",
      actDep:"Destination",
      delayDep:"RIGHT TIME",
      actHalt:"Destination",
      trainType:"SUF",
      pfNo:"4"
      } 
          ]
      }
      

      这是使用 Selenium 获取 HTML 和数据的解决方案。

      using System;
      using System.Collections.Generic;
      using System.Net;
      using HtmlAgilityPack;
      using OpenQA.Selenium.Firefox;
      using OpenQA.Selenium;
      using System.Threading;
      
      namespace test
      {
          class Program
          {
      
          public static void Main(string[] args)
          {
                  string url = "https://www.google.com";
                  IWebDriver driver = new FirefoxDriver();
                 driver.Navigate().GoToUrl("https://enquiry.indianrail.gov.in");
                  Console.WriteLine("Step 1");
                  driver.FindElement(By.XPath("//a[@id='ui-id-2']")).Click();
                  Thread.Sleep(10000);
                  Console.WriteLine("Step 2");
                  driver.FindElement(By.XPath("//input[@id='viaStation']")).SendKeys("NEW DELHI [NDLS]");
                  Thread.Sleep(2000);
                  Console.WriteLine("Step 3");
                  driver.FindElement(By.XPath("//button[@id='viaStnGoBtn']")).Click();
      
                  //PRESS A KEY WHEN THE HTML IS FULLY LOADED
                  Console.ReadKey();
      
      
      
                  HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
                  doc.LoadHtml(driver.PageSource);
      
                  HtmlNodeCollection nodeCol = doc.DocumentNode.SelectNodes("//body//tr[@class='altBG']");
                  foreach(HtmlNode node in nodeCol){
                      Console.WriteLine("Trip:");
                      foreach(HtmlNode child in node.ChildNodes)
                      {
                          Console.WriteLine("\t" + child.InnerText);
                      }
                  }
                  //Console.WriteLine(doc.DocumentNode.InnerHtml);
                  Console.ReadKey();
      
          }
      

      Thread.Sleep() 应该不是必需的。我只是将它们放入以防万一。如果您使用不同的驱动程序(例如 PhantomJS 无头驱动程序),也可以优化速度。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-28
        • 1970-01-01
        • 2016-09-27
        • 2013-02-16
        • 1970-01-01
        相关资源
        最近更新 更多