【发布时间】:2018-04-27 16:12:45
【问题描述】:
我想从this website获取信息
使用 HTML Agility Pack 进入我的 ASPX 页面。但我不能这样做,因为数据是在我搜索网页中的数据后加载的。
我需要在 5 分钟间隔后连续完成一些数据。
【问题讨论】:
标签: c# html asp.net html-agility-pack
我想从this website获取信息
使用 HTML Agility Pack 进入我的 ASPX 页面。但我不能这样做,因为数据是在我搜索网页中的数据后加载的。
我需要在 5 分钟间隔后连续完成一些数据。
【问题讨论】:
标签: c# html asp.net html-agility-pack
您提到的网站中的搜索结果是使用 Javascript 动态呈现的,并且数据通过 Ajax 以 Json 响应的形式出现。 HtmlAgilityPack 旨在解析 Html,而不是 Json。
考虑为 .Net 使用 Selenium 或 iMacros 驱动程序,或使用 Microsoft Framework 提供的 WebBrowser 类。这些工具在后台运行浏览器,因此它们可以在该页面中运行 Javascript 代码并呈现您想要抓取的 Html。
只需要设置适当的超时时间,这样他们就会一直等到搜索结果出现在页面上。
【讨论】:
正如@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 无头驱动程序),也可以优化速度。
【讨论】: