Продолжим тему работы с 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://www.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://www.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. www.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://www.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://www.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); ?>
Какой именно способ использовать целиком и полностью зависит от решаемой задачи и ваших предпочтений. Каждый из них имеет свои преимущества и недостатки.
Не стесняйтесь оставлять комментарии и задавать вопросы, ведь во многом от вас зависит о чем будет написано в следующий раз.
Очень интересная и полезная статья! Спасибо)
Пожалуйста, рад что это интересно не только мне.
Обращу внимание читателей на то, что 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.
Действительно, одна из ошибок была в регулярном выражении, использовал слеш как ограничитель… заменил на |, и ошибка исчезла.
но названия фильмов так и не выводятся. думаю, что проблема с авторизацией.. если разберусь, то выложу решение, вдруг, кому-нибудь понадобится
2 Кирилл
Наверное нужно адрес писать не watch.do , а watch.do/login
Чтобы куки всегда нормально находились, используйте эту регулярку:
#Set-Cookie: (.+)=(.+)(\n|;)#uisU
Думаю лучше писать dirname(__FILE__).’/cookie.txt’ в имени файла для куков. Иначе cookie.txt создается в папке с apache.
Думаю лучше использовать темповый путь что-то вроде tempnam(«/tmp», «curlcookie»);
«После получения размера заголовка мы можем разделить ответ на заголовок и тело (содержание).»
Зачем?
preg_match_all(«/Set-Cookie: (.*?)=(.*?);/i»,$header,$res);
Делал так:
preg_match_all(«/Set-Cookie: (\S+)/»,$header,$res);
Результат тот-же, разделить не проблема, а сама регулярка проще…
А вообще в общем и целом статья на 5+, если бы, когда я начинал cURL учить она мне попалась на глаза — избавила бы от многих часов ковыряния справочников и гугла 😀
Здравствуйте ..
У меня вот такой вопрос, как авторизоваться на сайте htpps://qiwi.ru пытаюсь уже несколько недель не получается если какие либо идеи может кто то сталкивался с этим, мне необходимо после авторизации проверить есть ли платежи и какие
спасибо большое за внимание …
буду очень рад любой поддержке …
Привет всем.
Конкретно в случае с вк тут всё очень просто. Код будет максимум 20 строчек.
Откройте нутро ссылки котлрая стоит после iframe src =’ и там все есть.
Я понемаю там задумка, теория, вариант. ..
А как же быть с видео. майлом.ру?
Кто-нить пробовал таким способом как написал автора получать ссылку на видео?