Вы можете сделать это в cURL без необходимости использования внешних «эмуляторов».
Приведенный ниже код извлекает страницу в переменную PHP для анализа.
Сценарий
Есть страница (назовем ее ГЛАВНАЯ), которая открывает сеанс. Серверная сторона, если она написана на PHP, — это та сторона (фактически любая), которая вызывает session_start()
в первый раз. На других языках вам нужна определенная страница, которая будет выполнять всю настройку сеанса. Со стороны клиента это страница, предоставляющая файл cookie идентификатора сеанса. В PHP это делают все сессионные страницы; на других языках это сделает лендинг, все остальные проверят, есть ли куки, а если нет, то вместо создания сеанса перебросит вас на ГЛАВНУЮ.
Существует страница (ВХОД), которая генерирует форму входа и добавляет в сеанс важную информацию - «Этот пользователь вошел в систему». В приведенном ниже коде это страница, запрашивающая идентификатор сеанса.
И, наконец, есть N страниц, на которых находятся полезные вещи.
Итак, мы хотим нажать HOME, затем LOGIN, затем GOODIES один за другим. Опять же, в PHP (и других языках) HOME и LOGIN вполне могут быть одной и той же страницей. Или все страницы могут иметь один и тот же адрес, например, в одностраничных приложениях.
Код
$url = "the url generating the session ID";
$next_url = "the url asking for session";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
// We do not authenticate, only access page to get a session going.
// Change to False if it is not enough (you'll see that cookiefile
// remains empty).
curl_setopt($ch, CURLOPT_NOBODY, True);
// You may want to change User-Agent here, too
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookiefile");
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookiefile");
// Just in case
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
$ret = curl_exec($ch);
// This page we retrieve, and scrape, with GET method
foreach(array(
CURLOPT_POST => False, // We GET...
CURLOPT_NOBODY => False, // ...the body...
CURLOPT_URL => $next_url, // ...of $next_url...
CURLOPT_BINARYTRANSFER => True, // ...as binary...
CURLOPT_RETURNTRANSFER => True, // ...into $ret...
CURLOPT_FOLLOWLOCATION => True, // ...following redirections...
CURLOPT_MAXREDIRS => 5, // ...reasonably...
CURLOPT_REFERER => $url, // ...as if we came from $url...
//CURLOPT_COOKIEFILE => 'cookiefile', // Save these cookies
//CURLOPT_COOKIEJAR => 'cookiefile', // (already set above)
CURLOPT_CONNECTTIMEOUT => 30, // Seconds
CURLOPT_TIMEOUT => 300, // Seconds
CURLOPT_LOW_SPEED_LIMIT => 16384, // 16 Kb/s
CURLOPT_LOW_SPEED_TIME => 15, //
) as $option => $value)
if (!curl_setopt($ch, $option, $value))
die("could not set $option to " . serialize($value));
$ret = curl_exec($ch);
// Done; cleanup.
curl_close($ch);
Реализация
Прежде всего, нам нужно получить страницу входа.
Мы используем специальный User-Agent, чтобы представиться, чтобы быть узнаваемыми (мы не хотим вызвать недовольство веб-мастера), а также обмануть сервер, заставив его отправить нам определенную версию сайта. это адаптировано для браузера. В идеале мы используем тот же User-Agent, что и любой браузер, который собираемся использовать для отладки страницы, плюс суффикс, чтобы тот, кто проверяет, понял, что это автоматизированный инструмент, на который они смотрят (см. комментарий Халфер).
$ua = 'Mozilla/5.0 (Windows NT 5.1; rv:16.0) Gecko/20100101 Firefox/16.0 (ROBOT)';
$cookiefile = "cookiefile";
$url1 = "the login url generating the session ID";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url1);
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookiefile);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookiefile);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, True);
curl_setopt($ch, CURLOPT_NOBODY, False);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, True);
$ret = curl_exec($ch);
Это приведет к получению страницы с запросом пользователя/пароля. Осматривая страницу, мы находим нужные поля (в том числе скрытые) и можем их заполнить. Тег FORM
говорит нам, нужно ли нам продолжать с POST или GET.
Мы можем захотеть проверить код формы, чтобы настроить следующие операции, поэтому мы просим cURL вернуть содержимое страницы как есть в $ret
и сделать вернуть тело страницы. Иногда CURLOPT_NOBODY
, установленного на True
, по-прежнему достаточно для запуска создания сеанса и отправки файлов cookie, и если это так, это происходит быстрее. Но CURLOPT_NOBODY
("нет тела") работает, выдавая запрос HEAD
вместо GET
; а иногда запрос HEAD
не работает, потому что сервер будет реагировать только на полный GET
.
Вместо того, чтобы извлекать тело таким образом, также можно войти в систему с помощью настоящего Firefox и обнюхать содержимое формы, публикуемое с помощью Firebug (или Chrome с инструментами Chrome); некоторые сайты пытаются заполнить/изменить скрытые поля с помощью Javascript, чтобы отправляемая форма была не той, которую вы видите в HTML-коде.
Веб-мастер, который хотел, чтобы его сайт не был очищен, может отправить скрытое поле с отметкой времени. Человеку (без помощи слишком умного браузера - есть способы сказать браузерам не быть умными; в худшем случае, каждый раз, когда вы меняете имя пользователя и поля ввода) требуется не менее трех секунд, чтобы заполнить форму. Сценарий cURL принимает ноль. Конечно, задержку можно смоделировать. Это все бой с тенью...
Мы также можем обратить внимание на внешний вид формы. Веб-мастер может, например, создать форму, запрашивающую имя, адрес электронной почты и пароль; а затем с помощью CSS переместите поле «электронная почта» туда, где вы ожидаете найти имя, и наоборот. Таким образом, отправляемая настоящая форма будет иметь "@" в поле с именем username
и ни одного в поле с именем email
. Сервер, который ожидает этого, просто снова инвертирует два поля. Созданный вручную "скребок" (или спам-бот) сделает то, что кажется естественным, и отправит электронное письмо в поле email
. И тем самым выдает себя. Проработав форму один раз в реальном браузере с поддержкой CSS и JS, отправив значимые данные и проанализировав, что на самом деле отправляется, мы возможно сможем преодолеть это конкретное препятствие. Может, потому что есть способы усложнить жизнь. Как я уже сказал, бой с тенью.
Вернемся к рассматриваемому случаю. В данном случае форма содержит три поля и не имеет наложения Javascript. У нас есть cPASS
, cUSR
и checkLOGIN
со значением «Проверить логин».
Итак, мы готовим форму с соответствующими полями. Обратите внимание, что форма должна быть отправлена как application/x-www-form-urlencoded
, что в PHP cURL означает две вещи:
- мы должны использовать
CURLOPT_POST
- параметр CURLOPT_POSTFIELDS должен быть строкой (массив будет сигнализировать cURL о необходимости отправки как
multipart/form-data
, что может работать... а может и нет).
Поля формы, как говорится, urlencoded; для этого есть функция.
Читаем поле action
формы; это URL-адрес, который мы должны использовать для отправки нашей аутентификации (которую мы должны иметь).
Итак, все готово...
$fields = array(
'checkLOGIN' => 'Check Login',
'cUSR' => 'jb007',
'cPASS' => 'astonmartin',
);
$coded = array();
foreach($fields as $field => $value)
$coded[] = $field . '=' . urlencode($value);
$string = implode('&', $coded);
curl_setopt($ch, CURLOPT_URL, $url1); //same URL as before, the login url generating the session ID
curl_setopt($ch, CURLOPT_POST, True);
curl_setopt($ch, CURLOPT_POSTFIELDS, $string);
$ret = curl_exec($ch);
Теперь мы ожидаем "Привет, Джеймс, как насчет хорошей игры в шахматы?" страница. Но более того, мы ожидаем, что сеанс, связанный с файлом cookie, сохраненным в $cookiefile
, был снабжен важной информацией — "пользователь прошел проверку подлинности".
Таким образом, всем последующим запросам страниц, сделанным с использованием $ch
и того же файла cookie, будет предоставлен доступ, что позволит нам довольно легко «очистить» страницы — просто не забудьте снова установить режим запроса на GET
:
curl_setopt($ch, CURLOPT_POST, False);
// Start spidering
foreach($urls as $url)
{
curl_setopt($ch, CURLOPT_URL, $url);
$HTML = curl_exec($ch);
if (False === $HTML)
{
// Something went wrong, check curl_error() and curl_errno().
}
}
curl_close($ch);
В цикле у вас есть доступ к $HTML
— HTML-коду каждой отдельной страницы.
Велик соблазн использования регулярных выражений. Вы должны сопротивляться этому. Чтобы лучше справляться с постоянно меняющимся HTML-кодом, а также не допускать ложных срабатываний или ложных отрицательных результатов, когда макет остается прежним, но содержание меняется (например, вы обнаружите, что у вас есть прогнозы погоды из Ниццы, Турретт-Левенс, Кастанье, но никогда не Аспремон или Гатьер, и разве это не любопытно?), лучший вариант — использовать DOM:
Захват атрибута href элемента A
person
LSerni
schedule
03.11.2012
CURLOPT_COOKIEJAR
иCURLOPT_COOKIEFILE
- person Lawrence Cherone   schedule 03.11.2012Set-Cookie
в ответ, когда он хочет, чтобы вы установили, обновили или удалили файлы cookie. Клиент отправляет заголовокCookie
в запросах, чтобы сообщить серверу, какие файлы cookie в данный момент активны у клиента. - person Esailija   schedule 03.11.2012