Продолжим тему работы с CURL на php. В четвертой части хотелось бы рассказать о работе с COOKIES. Вообще для работы с COOKIES есть стандартные средства, которые мы рассмотрим сегодня. А раз есть стандартные, значит, есть и нестандартные. На них мы обратим большую часть рассказа.

Стандартный способ работы с COOKIES
Стандартные способ работы с COOKIES основан на использовании файла, это простой и в тоже время действенный способ. Но в нем есть некоторые недостатки, к основным недостаткам я бы отнес следующие:
- сложность изменения COOKIES «на лету», в том числе доступ к ним и контроль;
- в случае, когда может выполняться несколько копий скрипта, возникает проблема уникальности имени файла.
Для того чтобы ваш скрипт начал работать с COOKIES, необходимо дополнительно установить два свойства:
-
<?php
-
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); //Из какого файла читать
-
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt"); //В какой файл записывать
-
?>
CURLOPT_COOKIEFILE – Имя файла из которого читаются, данные cookie. Данные могут быть либо в формате Netscape, либо просто HTTP-заголовки.
CURLOPT_COOKIEJAR – Имя файла в который, записываются полученные данные cookie. Данные могут быть либо в формате Netscape, либо просто HTTP-заголовки.
В общем весь пример будет выглядеть так:
-
<?php
-
$ch = curl_init();
-
curl_setopt($ch, CURLOPT_URL, 'http://blog.yousoft.ru/');
-
curl_setopt($ch, CURLOPT_HEADER, false);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
-
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
-
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
-
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP Bot (http://blog.yousoft.ru)');
-
$data = curl_exec($ch);
-
curl_close($ch);
-
?>
При этом данные в файле ‘cookie.txt’ будут содержать примерно следующее:
# Netscape HTTP Cookie File # http://curlm.haxx.se/rfc/cookie_spec.html # This file was generated by libcurl! Edit at your own risk. blog.yousoft.ru FALSE / FALSE 0 PHPSESSID 99764c90ef0e6ab84183938efcafd0f2
И для того, чтобы получить возможность прочить эти данные или изменить, нам нужно сделать парсинг этого файла. Который между прочим может быть и другого формата, а именно «просто HTTP-заголовки».
Нестандартный или ручной вариант
У этого варианта также есть и своим преимущества и свои недостатки. К недостатком можно отнести:
- необходимость дополнительной обработки для получения и отправки COOKIES;
- необходимы дополнительные действия для хранения COOKIES между запусками скрипта.
Как известно, COOKIES передается в заголовке HTTP ответ, следовательно, нам необходимо установить в настройках CURL установить свойство CURLOPT_HEADER в true, чтобы мы могли получить заголовки.
-
<?php
-
curl_setopt($ch, CURLOPT_HEADER, true);
-
?>
Следующим шагом нам необходимо разделить полученный результат на заголовок и тело (содержание) ответа. Для этого мы будем использовать функцию curl_getinfo, которая возвращает информацию о последней операции.
-
<?php
-
string curl_getinfo ( resource $ch [, int $opt] )
-
?>
Нас интересует параметр CURLINFO_HEADER_SIZE.
CURLINFO_HEADER_SIZE – Суммарный размер всех полученных заголовков
После получения размера заголовка мы можем разделить ответ на заголовок и тело (содержание).
-
<?php
-
$header=substr($data,0,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
-
$body=substr($data,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
-
?>
Теперь необходимо выделить непосредственно сами COOKIES, и сформировать строку для того чтобы можно было передать эти COOKIES в следующем запросе.
-
<?php
-
preg_match_all("/Set-Cookie: (.*?)=(.*?);/i",$header,$res);
-
$cookie='';
-
foreach ($res[1] as $key => $value) {
-
//Здесь можно провести любую обработку COOKIES
-
$cookie.= $value.'='.$res[2][$key].'; ';
-
};
-
?>
Для того, чтобы CURL передавал COOKIES при запросе нужно их установить. Для этого используем свойство CURLOPT_COOKIE.
CURLOPT_COOKIE – Содержимое заголовка «Cookie: «, который будет отправлен с HTTP запросом.
А, теперь совместим все вместе:
-
<?php
-
$cookie='';
-
$ch = curl_init();
-
curl_setopt($ch, CURLOPT_URL, 'http://blog.yousoft.ru/');
-
curl_setopt($ch, CURLOPT_HEADER, true);
-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-
curl_setopt($ch, CURLOPT_COOKIE,$cookie);
-
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
-
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP Bot (http://blog.yousoft.ru)');
-
$data = curl_exec($ch);
-
$header=substr($data,0,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
-
$body=substr($data,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
-
preg_match_all("/Set-Cookie: (.*?)=(.*?);/i",$header,$res);
-
$cookie='';
-
foreach ($res[1] as $key => $value) {
-
$cookie.= $value.'='.$res[2][$key].'; ';
-
};
-
curl_close($ch);
-
?>
Какой именно способ использовать целиком и полностью зависит от решаемой задачи и ваших предпочтений. Каждый из них имеет свои преимущества и недостатки.
Не стесняйтесь оставлять комментарии и задавать вопросы, ведь во многом от вас зависит о чем будет написано в следующий раз.
Похожие записи:
- Используем CURL (php) часть 2 (отправка GET и POST запросов)
- Используем CURL (php) часть 1
- Используем CURL (php) практика: 20 последних запросов пользователей Яндекса
- Используем CURL (php) часть 3 (протокол – HTTPS, SSL соединение)
- curl в php практическое применение
Метки: curl

Очень интересная и полезная статья! Спасибо)
Пожалуйста, рад что это интересно не только мне.
Обращу внимание читателей на то, что UserAgent лучше прописывать какой-нибудь правдоподобный, соответствующий реальному UserAgent-у браузера. Так меньше вероятность того, что вашего бота забанят в robots.txt, если вы «переусердствуете» с количеством и частотой запросов к сайту
Во втором варианте для нахождения заголовка с куками, я бы использовал опцию CURLOPT_HEADERFUNCTION. Меньше парсить придется, да и вообще, так можно все заголовки собрать, что нужно. Так можно и тело парсить еще вовремя получения (только с CURLOPT_WRITEFUNCTION). Можно сбросить соединение, если чего то не то. Короче быстрее и функциональнее.
Orme:
С Вами можно согласиться и не согласиться. Насчет меньше парсить не уверен, с учетом того, что нужно еще определить callback функцию, кода получиться столько же если не больше. Быстрее тоже врядли… А вот то, что функциональнее это да, но не всегда нужна эта фунциональность.
Спасибо Вам за комментарий, в ближайшее время я напишу и про этот способ.
есть еще способ решить все просто (на мой взгляд) это использовать в названии файла куки часть идентификатора сессии. Тут сразу можно увидеть недостатки, необходимость очистки или создания пустого файла куки, нагрузка на хард. Способ №2 сказанный в статстатьтоже имеет свои недостатки, а именно сложность алгоритма (конечно все отностительно но надо стримится к простому коду) + нагрузка на сервер (память, время процессора).
я дурак.
объясните магию строки:
preg_match_all(«/Set-Cookie: (.*?)=(.*?);/i»,$header,$res);
спасибо
сделал так, но полученые кукис не устанавлюваются
В Set-Cookie не обязательно есть «;» эта регулярка не найдет такую куку.
Пример:
HTTP/1.1 200 OK
Date: Fri, 28 Jan 2011 13:24:27 GMT
Server: Apache
Set-Cookie: APSSSN=12962210676733764
Content-Length: 2926
Content-Type: text/html; charset=utf8
А ещё регулярка не найдет, если куки передали так:
Set-Cookie: a=b;c=d;f=aa
Спасибо. Помог второй вариант обмануть хитрые противоскачиватели
Здравствуйте, решил попробовать залогиниться в watch.do и вывести потом от туда заголовки фильмов с первой страницы.
вот код:
http://clip2net.com/s/1nE0J
при обработке выводи надпись PHPSESSID
где ошибка? буду благодарен за помощь
Без доступа к watch.do сложно что-то сказать, нужно смотреть, что он отдает. Но вполне возможно, что 23 строка все таки лишняя, или проблемы с разбором уже самого html в строке 24.
Действительно, одна из ошибок была в регулярном выражении, использовал слеш как ограничитель… заменил на |, и ошибка исчезла.
но названия фильмов так и не выводятся. думаю, что проблема с авторизацией.. если разберусь, то выложу решение, вдруг, кому-нибудь понадобится