ASP.NET屏幕刮后模拟

时间:2009-07-23 15:16:33

标签: javascript html checkbox parsing screen-scraping

我正在尝试下载并解析网页的HTML。最近,源网站从一个页面上的所有信息转移到隐藏在javascript后面的部分。有一个“全部显示”复选框,需要激活才能查看整个页面。

以下是网站:Source Website

基本上我希望在单击复选框后自动检索该页面。目前,我们有一个C程序可以下载网页并处理我们的解析。我不确定它是否可以接受URL中的javascript,如果可以用来解决这个问题(我已经尝试使用书签来从URL调用javascript,但我无法让它来处理复选框),但如果更容易编写可以处理此问题的C#程序,它可以处理文件。

我更喜欢自己编写代码的方法,而不是使用第三方程序来避免在运行的服务器上安装任何东西。非常感谢任何帮助。


编辑:基本上,如何自动调用链接到“全选”复选框的javascript,这样我就可以抓住包含复选框后显示的所有内容的html页面。 / p>


编辑2: 这是Fiddler2的输出:

__EVENTTARGET ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox
__EVENTARGUMENT
__LASTFOCUS
__VIEWSTATE (REMOVED DUE TO LENGTH)
__EVENTVALIDATION (REMOVED DUE TO LENGTH)
ctl00$ContentPlaceHolder1$GenericWebUserControl$Organization0 ALL
ctl00$ContentPlaceHolder1$GenericWebUserControl$Initial or Amendment1 ALL
ctl00$ContentPlaceHolder1$GenericWebUserControl$Relief Requested2 ALL
ctl00$ContentPlaceHolder1$GenericWebUserControl$Country3 ALL
ctl00$ContentPlaceHolder1$GenericWebUserControl$Status4 ALL
ctl00$ContentPlaceHolder1$GenericWebUserControl$StartDate5  
ctl00$ContentPlaceHolder1$GenericWebUserControl$EndDate5    
ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox on

我目前从服务器获得500个错误。我是否还需要在帖子请求中包含所有这些GenericWebUserControls?我还需要包含EVENTVALIDATION吗?


编辑3: 这是最新的代码。我仍然收到服务器500错误。

private void CreateRequest()
{
    HttpWebRequest httpWebRequest;
    HttpWebResponse httpWebResponse;
    StreamWriter streamWriter;
    Stream webResponseStream;
    StreamReader streamReader;
    string postData;
    string outputHTML;

    postData = String.Format("&__EVENTTARGET={0}" + "&__VIEWSTATE={1}" + "&__EVENTVALIDATION=(2)"+"&ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox=on" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Organization0=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Initial+or+Amendment1=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Relief+Requested2=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Country3=ALL" +"&ctl00$ContentPlaceHolder1$GenericWebUserControl$Status4=ALL",EVENTTARGET, VIEWSTATE, EVENTVALIDATION);

    httpWebRequest = (HttpWebRequest)WebRequest.Create("http://services.cftc.gov/sirt/sirt.aspx?Topic=ForeignPart30Exemptions");
    httpWebRequest.Method = "POST";
    httpWebRequest.ContentType = "application/x-www-form-urlencoded";
    httpWebRequest.ContentLength = postData.Length;

    streamWriter = new StreamWriter(httpWebRequest.GetRequestStream(), System.Text.Encoding.ASCII);
    streamWriter.Write(postData);
    streamWriter.Close();

    httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();

    webResponseStream = httpWebResponse.GetResponseStream();
    streamReader = new StreamReader(webResponseStream);
    outputHTML = streamReader.ReadToEnd();

    Console.WriteLine(outputHTML);
}

编辑4: 我已经确定它是导致服务器500错误的postData字符串。如果我将其设为空字符串,则会输出整个网页。有没有人知道我是否正确必须将来自Fiddler2的所有值都放入postData字符串?此外,__VIEWSTATE是一个非常长的字符串。是否有限制或任何我不确定的事情?


编辑5: 我通过URL编码器运行了postData中使用的所有字符串,但我仍然遇到服务器500错误。有没有办法让我调试帖子正文无效的原因?


解: 好吧,我无法使我的postData字符串正确,但是当我粘贴在原始的POST主体中时,它可以工作。这看起来已经足够好了,但我担心的是这是否会继续有效。

2 个答案:

答案 0 :(得分:3)

这是一个asp.net页面。单击该复选框会将页面发回服务器。因此,不是试图模拟javascript而是模拟帖子请求。

这对ASP.Net页面来说非常棘手,因为您通常需要填充隐藏的__ViewState输入。我建议使用像Fiddler这样的数据包嗅探器来查看发送时的实际请求。您应该能够从那里复制ViewState。

答案 1 :(得分:1)

看起来JavaScript启动了对同一页面的POST。 Firebug在POST数据中显示以下内容。

__EVENTTARGET: ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox

这可能是一个开始寻找的好地方。