使用AJAX分页从所有asp.net页面中刮取数据

Sub*_*axe 15 php asp.net curl screen-scraping web-scraping

我想废弃一个包含地址,电子邮件等用户列表的网页.网页包含分页用户列表,即当我点击第2页链接时页面包含10个用户链接它将通过AJAX加载用户列表第2页并更新列表所以所有分页链接.

网站是在asp扩展.aspx页面开发的,因为我对asp.net一无所知以及asp如何管理分页和AJAX

我使用简单的html dom http://sourceforge.net/projects/simplehtmldom/来废弃包含

对于拥有用户的页面,<=10 我不必模拟AJAX请求,就像用户点击分页链接一样

但对于有分页从其他页面获取数据的页面,我正在模拟后AJAX请求

require 'simple_html_dom.php';

$html = file_get_html('www.example.com/user_list.aspx');

$viewstate = $html->find("#__VIEWSTATE");
$viewstate = $viewstate[0]->attr['value'];

$eventvalidation        = $html->find("#__EVENTVALIDATION");
$eventvalidation        = $eventvalidation[0]->attr['value'];
$number_of_pageinations = 3;

$pageNumberCodes = array(
    'ctl00$cphMainContent$rdpMembers$ctl01$ctl01',
    'ctl00$cphMainContent$rdpMembers$ctl01$ctl02',
    'ctl00$cphMainContent$rdpMembers$ctl01$ctl03'
); // this code is added for each page in POST  as  __EVENTTARGET 

for ($i = 0; $i < $number_of_pageinations; $i++) {
    $options = array(
        CURLOPT_RETURNTRANSFER => true, // return web page
        CURLOPT_HEADER => false, // don't return headers
        CURLOPT_ENCODING => "", // handle all encodings
        CURLOPT_USERAGENT => "Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7'", // who am i
        CURLOPT_AUTOREFERER => true, // set referer on redirect
        CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
        CURLOPT_TIMEOUT => 1120, // timeout on response
        CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
        CURLOPT_POST => true,
        CURLOPT_VERBOSE => true,
        CURLOPT_POSTFIELDS => urlencode('ctl00%24scriptManager=ctl00%24cphMainContent%24ctl00%24cphMainContent%24rdpMembersPanel%7C' . $pageNumberCodes[0] . '&__EVENTTARGET=' . $pageNumberCodes[0] . '&__EVENTARGUMENT=' . '&__VIEWSTATE=' . $viewstate . '&__EVENTVALIDATION=' . $eventvalidation . "&google=" . '&ctl00%24cphMainContent%24txtZip=' . '&ctl00%24cphMainContent%24cboRadius=Exact' . '&ctl00%24cphMainContent%24txtMemberName=' . '&ctl00%24cphMainContent%24txtCity=Honolulu' . '&ctl00%24cphMainContent%24cboState=HI' . '&ctl00%24cphMainContent%24txtAddress=' . '&ctl00_cphMainContent_rdpMembers_ClientState=' . '&ctl00%24cphMainContent%24ddList=-Select%20field%20to%20sort-' . '&ctl00_cphMainContent_ddList_ClientState=' . '&ctl00_cphMainContent_rdlMembers_ClientState=' . '&ctl00_cphMainContent_ddList_ClientState=' . '&ctl00_cphMainContent_rdlMembers_ClientState=' . '&ctl00_cphMainContent_rdpMembers1_ClientState=' . '&__ASYNCPOST=true' . 'RadAJAXControlID=ctl00_cphMainContent_RadAjaxManager1')
    );
    $ch      = curl_init($url);
    curl_setopt_array($ch, $options);
    $return = curl_exec($ch);
    curl_close($ch);
    echo $return;

    $newHtml = str_get_html($return);

    $viewstate = $newHtml->find("#__VIEWSTATE");
    $viewstate = $viewstate[0]->attr['value'];

    $eventvalidation = $newHtml->find("#__EVENTVALIDATION");
    $eventvalidation = $eventvalidation[0]->attr['value'];
}
Run Code Online (Sandbox Code Playgroud)

这应该回显来自不同页面的数据,但是它总是打印第一页的数据,任何人都可以指出我在哪里和缺少什么我不知道asp如何管理分页和AJAX请求以及是什么__EVENTARGUMENT,__VIEWSTATE以及__EVENTVALIDATION

Kna*_*ģis 27

通常,为了伪造ASP.NET网站认为您实际按下按钮(更一般地说 - 执行回发),您需要执行以下操作:

  1. 获取页面上每个INPUT和SELECT元素的值.在每种情况下可能都不需要它,但是您应该始终至少获取名称以"__"开头的所有隐藏字段的值(例如__VIEWSTATE).你真的不需要知道它们写的是什么 - 只是它们中的值必须不变地发送回服务器.

  2. 创建对服务器的POST请求.您需要使用经典POST,避免任何AJAX请求.使用某些浏览器插件(在Firefox或Chrome中)可能会禁用XMLHttpRequest,因此您可以使用Fiddler等工具拦截非AJAX请求.

  3. 将#1中的每个值添加到该发布请求中.您只需要覆盖两个值:__ EVENTTARGET和__EVENTARGUMENT.除非您尝试模仿的链接或按钮具有onclick类似的处理程序,否则您将留空<a href="javascript:__doPostBack('ctl00$login','')">.如果是,则解析来自此链接的值 - 第一个是事件目标(通常它将匹配页面上某个元素的ID),第二个是事件参数.

  4. 如果您正确执行了请求,则应该返回HTML页面.如果获得部分响应,请检查是否未传递要求异步结果的HTTP标头.