Я хочу отменить веб-страницу, содержащую список пользователей с адресами, электронной почтой и т. Д. На странице есть список пользователей с разбивкой по страницам, т. Е. Страница содержит 10 пользователей, когда я нажимаю на ссылку 2, она будет загружать список пользователей со 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, чтобы затем перехватить запрос без AJAX с помощью таких инструментов, как Fiddler.
Добавьте каждое значение от # 1 к этому сообщению. Для перезаписывания требуется только два значения: __EVENTTARGET и __EVENTARGUMENT. Вы оставите их пустыми, если только ссылка или кнопка, которую вы пытаетесь имитировать, имеют обработчик onclick
например <a href="javascript:__doPostBack('ctl00$login','')">
. Если это так, проанализируйте значения из этой ссылки – первая – это цель события (обычно она будет соответствовать идентификатору какого-либо элемента на странице), второй – аргумент события.
Если вы правильно выполнили запрос, вам нужно вернуть HTML-страницу. Если вы получите частичный ответ, проверьте, не прошел ли HTTP-заголовок, который запрашивает результат async.
Мой лучший совет – использовать iMacros https://addons.mozilla.org/en-US/firefox/addon/imacros-for-firefox/
iMacros:
Независимо от того, является ли это 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'