【问题标题】:ASP.NET Screen Scrape Post SimulateASP.NET 屏幕抓取后模拟
【发布时间】:2009-07-23 15:16:33
【问题描述】:

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

这是网站:Source Website

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

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


编辑:基本上,我怎样才能自动调用链接到“全选”复选框的 javascript,以便我可以抓取包含单击复选框后显示的所有内容的 html 页面。


编辑 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 正文中时它可以工作。这看起来已经足够了,但我担心这是否会继续工作。

【问题讨论】:

  • 你能把它当作一个问题来表达吗?

标签: javascript html checkbox parsing screen-scraping


【解决方案1】:

这是一个 asp.net 页面。单击复选框会导致页面被回发到服务器。因此,与其尝试模拟 javascript,不如模拟发布请求。

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

【讨论】:

  • 好的,所以我运行了嗅探器并进入 ViewState 输入。我假设我现在可以运行一个 C# HttpWebRequest 来模拟发布请求。我唯一的另一个问题是 ViewState 会改变吗?
  • 可能。 ViewState 可能会存储用户令牌、面包屑等内容。您可以在其中放置很多东西。但您最关心的是,如果 EnableEventValidation 设置为 true(默认)并且您的复选框输入具有正确的值,它是“有效的”。
  • 知道为什么我会收到服务器 500 错误吗?我假设发布机制有问题。
  • 你必须玩它。尝试为您的请求设置用户代理。
  • 用户代理不走运。如果您查看我上面的代码,您知道 postData 字符串是否正确吗?我还发布了 Fiddler2 输出,我只是将每个具有值的输出添加到 postData 字符串中。
【解决方案2】:

看起来 JavaScript 向同一页面发起了 POST。 Firebug 在 POST 数据中显示以下内容。

__EVENTTARGET: ctl00$ContentPlaceHolder1$GenericWebUserControl$ShowAllCheckBox

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

【讨论】:

  • 那么我可以使用 C# HttpWebRequest POST 方法来做到这一点吗?我对网络编程不是很熟悉。我是否需要使用数据包嗅探方法来获取我需要的信息?
  • Firebug 也可以,但是有很多 javascript 可以使用。您只需要 一些东西 来显示最终将哪些数据发布到服务器,这样您就可以模拟相同的请求。
猜你喜欢
  • 1970-01-01
  • 2021-01-24
  • 2011-02-20
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 2019-01-17
相关资源
最近更新 更多