Разберем сразу на примере. Так как принципы работы такие же, что и принципы работы с POST-запросами в Delphi (см. статью Пример авторизации на сайте с помощью idHTTP.Post), то и пример возьму тот же, что и в той статье, а именно — авторизация в ЖЖ.
При организации POST-запроса достаточно будет добавить в свойства объекта curl параметр CURLOPT_POST, установленный в 1 (или true) и CURLOPT_POSTFIELDS, значением которого будет строка со значениями переменных в таком виде:
param1=value1¶m2=value2¶m3=value3&...¶mN=valueN
По аналогии с функцей get_web_page($url), которую мы рассматривали в обзорной статье о CURL, создадим функцию, отправляющую POST-запрос.
function post_content ($url,$postdata) {
$uagent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_USERAGENT, $uagent);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_COOKIEJAR, "z://coo.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE,"z://coo.txt");
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
В качестве входных параметров будут адрес и строка с переменными и их значениями.
Для работы с кукисами надо присвоить двум параметрам значение, соответствующее пути до файла, в котором будут храниться кукисы (я писала скрипт на локальной машине, в путях прописала файл на диске).
curl_setopt($ch, CURLOPT_COOKIEJAR, "z://coo.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE,"z://coo.txt");
Они отвечают за запись и чтение кукисов из файла. Содержимое файла после запуска скрипта получилось примерно следующее (все данные я параноидально заблурила, но они там есть :) ):
Можете также самостоятельно почитать про немного другой способ организации использования кукисов, через параметр CURLOPT_COOKIE. Здесь я о нем говорить не буду.
Используя описанную выше функцию, напишем простенький код для логина в ЖЖ. После логина все кукисы будут сохранены в файл, последующая загрузка других страниц ЖЖ будет осуществлена уже "от лица" того пользователя, под которым мы залогинены.
<?php
function get_web_page( $url )
{
$uagent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // возвращает веб-страницу
curl_setopt($ch, CURLOPT_HEADER, 0); // не возвращает заголовки
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // переходит по редиректам
curl_setopt($ch, CURLOPT_ENCODING, ""); // обрабатывает все кодировки
curl_setopt($ch, CURLOPT_USERAGENT, $uagent); // useragent
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); // таймаут соединения
curl_setopt($ch, CURLOPT_TIMEOUT, 120); // таймаут ответа
curl_setopt($ch, CURLOPT_MAXREDIRS, 10); // останавливаться после 10-ого редиректа
curl_setopt($ch, CURLOPT_COOKIEJAR, "z://coo.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE,"z://coo.txt");
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
function post_content ($url,$postdata) {
$uagent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)";
$ch = curl_init( $url );
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_USERAGENT, $uagent); // useragent
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt($ch, CURLOPT_COOKIEJAR, "z://coo.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE,"z://coo.txt");
$content = curl_exec( $ch );
$err = curl_errno( $ch );
$errmsg = curl_error( $ch );
$header = curl_getinfo( $ch );
curl_close( $ch );
$header['errno'] = $err;
$header['errmsg'] = $errmsg;
$header['content'] = $content;
return $header;
}
$url = 'http://www.livejournal.com/login.bml?ret=1';
$username = 'xxx';
$userpass = 'yyy';
// формируем строку с данными
$postdata = 'mode=login&user='.$username.'&password='.$userpass;
$result = post_content( $url, $postdata );
$html = $result['content'];
// загружаем любую другую страницу ЖЖ. Пользователь, под логином которого вошли, должен сохраниться
$url = 'http://'.$username.'.livejournal.com/';
$result = get_web_page( $url );
$html = $result['content'];
$pos = StrPos($html,"<input class='logoutlj_hidden' id='user' name='user' type='hidden' value='".$username."'");
if ( $pos === false ) {
echo 'Авторизация провалилась';
}
else {
echo 'Авторизация прошла успешно';
}
?>
Это все. Теперь вы, например, сможете парсить документы, доступные только зарегистрированным пользователям.
_____
Стандартный блок в конце последних моих постов — объявление благодарности за информационную поддержку. Спасибо автору серьезного блога о главном и мелочах.
_____
Чтобы быть в курсе обновлений блога, можно подписаться на RSS.
$html = $result['content']; встречается в коде дважды, зачем первый раз?
ОтветитьУдалить@Emogot, я для себя тестировала, можно убрать.
ОтветитьУдалитьMasha, спасибо за функции post_content и get_web_page
ОтветитьУдалитьна их основе можно делать все запросы
Вот не пойму: зарегистрировался на ЖЖ и скопировал последний код. Ввел свой логин и пароль ($username = 'xxx'; $userpass = 'yyy';), а мне пишет "Авторизация провалилась". В чем может быть проблема?
ОтветитьУдалитьPS: cURL - вроди как настроил ( http://a-smile.narod.ru/img/1.jpeg )
vah-smile, с тех пор, как была написана статья, ЖЖ поменял html-код. Вместо
ОтветитьУдалитьinput type='hidden' name='user' value='
напишите при проверке:
input class='logoutlj_hidden' id='user' name='user' type='hidden' value='
(на всякий случай перепроверьте, посмотрев исходный код).
Хмм...
ОтветитьУдалить$postdata = 'mode=login&user='.$username.'&password='.$userpass;
$result = post_content( $url, $postdata );
Намного улучшаем читабельность кода используя стандартные методы php,
избавляем код от возможных синтаксических ошибок...
$result = post_content( $url, array(
'mode'=>'login',
'username'=> $username,
'password' => $userpass));
Исправление в теле функции
curl_setopt($ch, CURLOPT_POSTFIELDS, $postdata);
на
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postdata));
Не хотел-бы я видеть поведение кода если пароль 'super&man' :)
Исправление нормально заэскейпит данные и точно передаст в валидном формате.