Используем CURL (php) часть 4 (работаем с COOKIES, 2 способа)

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

Изучаем curl 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);
?>

Какой именно способ использовать целиком и полностью зависит от решаемой задачи и ваших предпочтений. Каждый из них имеет свои преимущества и недостатки.

Не стесняйтесь оставлять комментарии и задавать вопросы, ведь во многом от вас зависит о чем будет написано в следующий раз.

Используем CURL (php) часть 4 (работаем с COOKIES, 2 способа): 21 комментарий

  1. Обращу внимание читателей на то, что UserAgent лучше прописывать какой-нибудь правдоподобный, соответствующий реальному UserAgent-у браузера. Так меньше вероятность того, что вашего бота забанят в robots.txt, если вы «переусердствуете» с количеством и частотой запросов к сайту 🙂

  2. Во втором варианте для нахождения заголовка с куками, я бы использовал опцию CURLOPT_HEADERFUNCTION. Меньше парсить придется, да и вообще, так можно все заголовки собрать, что нужно. Так можно и тело парсить еще вовремя получения (только с CURLOPT_WRITEFUNCTION). Можно сбросить соединение, если чего то не то. Короче быстрее и функциональнее.

  3. Orme:
    С Вами можно согласиться и не согласиться. Насчет меньше парсить не уверен, с учетом того, что нужно еще определить callback функцию, кода получиться столько же если не больше. Быстрее тоже врядли… А вот то, что функциональнее это да, но не всегда нужна эта фунциональность.

    Спасибо Вам за комментарий, в ближайшее время я напишу и про этот способ.

  4. есть еще способ решить все просто (на мой взгляд) это использовать в названии файла куки часть идентификатора сессии. Тут сразу можно увидеть недостатки, необходимость очистки или создания пустого файла куки, нагрузка на хард. Способ №2 сказанный в статстатьтоже имеет свои недостатки, а именно сложность алгоритма (конечно все отностительно но надо стримится к простому коду) + нагрузка на сервер (память, время процессора).

  5. В 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

  6. Здравствуйте, решил попробовать залогиниться в watch.do и вывести потом от туда заголовки фильмов с первой страницы.
    вот код:
    http://clip2net.com/s/1nE0J

    при обработке выводи надпись PHPSESSID
    где ошибка? буду благодарен за помощь

  7. Без доступа к watch.do сложно что-то сказать, нужно смотреть, что он отдает. Но вполне возможно, что 23 строка все таки лишняя, или проблемы с разбором уже самого html в строке 24.

  8. Действительно, одна из ошибок была в регулярном выражении, использовал слеш как ограничитель… заменил на |, и ошибка исчезла.
    но названия фильмов так и не выводятся. думаю, что проблема с авторизацией.. если разберусь, то выложу решение, вдруг, кому-нибудь понадобится

  9. Чтобы куки всегда нормально находились, используйте эту регулярку:

    #Set-Cookie: (.+)=(.+)(\n|;)#uisU

  10. Думаю лучше писать dirname(__FILE__).’/cookie.txt’ в имени файла для куков. Иначе cookie.txt создается в папке с apache.

  11. «После получения размера заголовка мы можем разделить ответ на заголовок и тело (содержание).»

    Зачем?

    preg_match_all(«/Set-Cookie: (.*?)=(.*?);/i»,$header,$res);

    Делал так:

    preg_match_all(«/Set-Cookie: (\S+)/»,$header,$res);

    Результат тот-же, разделить не проблема, а сама регулярка проще…

    А вообще в общем и целом статья на 5+, если бы, когда я начинал cURL учить она мне попалась на глаза — избавила бы от многих часов ковыряния справочников и гугла 😀

  12. Здравствуйте ..
    У меня вот такой вопрос, как авторизоваться на сайте htpps://qiwi.ru пытаюсь уже несколько недель не получается если какие либо идеи может кто то сталкивался с этим, мне необходимо после авторизации проверить есть ли платежи и какие

    спасибо большое за внимание …
    буду очень рад любой поддержке …

  13. Привет всем.
    Конкретно в случае с вк тут всё очень просто. Код будет максимум 20 строчек.
    Откройте нутро ссылки котлрая стоит после iframe src =’ и там все есть.
    Я понемаю там задумка, теория, вариант. ..
    А как же быть с видео. майлом.ру?
    Кто-нить пробовал таким способом как написал автора получать ссылку на видео?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.