我想废弃一个包含带有地址、电子邮件等的用户列表的网页。网页包含带分页的用户列表,即页面包含 10 个用户,当我单击第 2 页链接时,它将通过 AJAX 加载第二页的用户列表并更新列表所有分页链接均如此。
网站是用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如何管理分页和AJAX请求以及什么是
__EVENTARGUMENT
,__VIEWSTATE
和__EVENTVALIDATION
一般来说,为了让 ASP.NET 网站认为您实际上按下了按钮(更一般地说 - 执行回发),您需要执行以下操作:
获取页面上每个 INPUT 和 SELECT 元素的值。可能并非在每种情况下都需要它,但您应该始终至少获取名称以“__”开头的所有隐藏字段(例如 __VIEWSTATE)的值。您实际上并不需要知道其中写入的内容 - 只需将其中的值不变地发送回服务器即可。
创建到服务器的 POST 请求。您需要使用经典的 POST,避免任何 AJAX 请求。使用某些浏览器插件(在 Firefox 或 Chrome 中),可以禁用 XMLHttpRequest,这样您就可以使用 Fiddler 等工具拦截非 AJAX 请求。
将 #1 中的每个值添加到该发布请求中。您只需覆盖两个值:__EVENTTARGET 和 __EVENTARGUMENT。您可以将这些留空,除非您尝试模仿的链接或按钮具有像
onclick
这样的 <a href="javascript:__doPostBack('ctl00$login','')">
处理程序。如果是,则解析此链接中的值 - 第一个是事件目标(它通常会匹配页面上某些元素的 ID),第二个是事件参数。如果正确执行了请求,您应该返回 HTML 页面。如果您得到部分响应,请检查您是否未传递请求异步结果的 HTTP 标头。
我最好的建议是使用 iMacros https://addons.mozilla.org/en-US/firefox/addon/imacros-for-firefox/
i宏:
无论是 ajax - .aspx、.jsp 还是 .php。
我建议扩展到 Ruby 并尝试 Capybara,这是使用 Selenium 的明智方法。它允许您访问页面,然后检查实际的 DOM。你可以点击所有内容,等待事件等等。它使用真正的浏览器。
visit "http://www.google.com"
page.find("button[name=btnK]")
我得到了一些使用你的代码作为基础的测试代码,我发现的唯一问题是这一行。
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'