2013-02-08 36 views
15

我想要使用地址,电子邮件等方式来截取包含用户列表的网页网页包含用户分页的页面,即当页面点击第2页时页面包含10个用户链接它将通过AJAX加载用户列表第二页,并为所有分页链接更新列表等。使用AJAX分页方式从所有asp.net页面中刮去数据

网站是与扩展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']; 
} 

这应该呼应,从不同的页面数据,但它始终打印第一页的数据,任何人可以点我在哪里,我拨错的,什么是缺少 我不知道ASP如何管理paginations和AJAX请求,什么是__EVENTARGUMENT__VIEWSTATE__EVENTVALIDATION

+2

发布的URL将是有益的。您可能有幸使用[此图书馆](http://scraperblog.blogspot.com/2012/11/introducing-pgbrowser.html) – pguardiario

+0

来检查您可以使用的发布请求标题和内容http://www.fiddler2.com/fiddler2/ –

+0

我认为你需要添加网址.... – Baba

回答

27

在一般情况下,为了伪造ASP.NET网站认为你实际上按下一个按钮(在更一般的 - 进行回传),你需要做到以下几点:

  1. 获取每一个IN的值页面上的PUT和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标头。

2

我会推荐分支到Ruby并尝试Capybara这是一个使用硒的理智方式。它可以让你访问一个页面,然后检查实际的DOM。您可以点击所有内容,等待事件等。它使用真正的浏览器。

visit "http://www.google.com" 
page.find("button[name=btnK]") 
0

我得到了一些测试代码工作使用你的基础,我发现的唯一问题是这条线。

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') 

将需要进行urlencode窥测像这样

CURLOPT_POSTFIELDS => 'ctl00%24scriptManager=ctl00%24cphMainContent%24ctl00%24cphMainContent%24rdpMembersPanel%7C' . $pageNumberCodes[0] . '&__EVENTTARGET=' . $pageNumberCodes[0] . '&__EVENTARGUMENT=' . '&__VIEWSTATE=' . rawurlencode($viewstate) . '&__EVENTVALIDATION=' . rawurlencode($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'