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


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

Изучаем curl COOKIES

Стандартный способ работы с COOKIES

Стандартные способ работы с COOKIES основан на использовании файла, это простой и в тоже время действенный способ. Но в нем есть некоторые недостатки, к основным недостаткам я бы отнес следующие:

  • сложность изменения COOKIES «на лету», в том числе доступ к ним и контроль;
  • в случае, когда может выполняться несколько копий скрипта, возникает проблема уникальности имени файла.

Для того чтобы ваш скрипт начал работать с COOKIES, необходимо дополнительно установить два свойства:

  1. <?php
  2. curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); //Из какого файла читать
  3. curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt"); //В какой файл записывать
  4. ?>

CURLOPT_COOKIEFILE — Имя файла из которого читаются, данные cookie. Данные могут быть либо в формате Netscape, либо просто HTTP-заголовки.

CURLOPT_COOKIEJAR — Имя файла в который, записываются полученные данные cookie. Данные могут быть либо в формате Netscape, либо просто HTTP-заголовки.

В общем весь пример будет выглядеть так:

  1. <?php
  2. $ch = curl_init();
  3. curl_setopt($ch, CURLOPT_URL, 'http://blog.yousoft.ru/');
  4. curl_setopt($ch, CURLOPT_HEADER, false);
  5. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  6. curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
  7. curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
  8. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  9. curl_setopt($ch, CURLOPT_USERAGENT, 'PHP Bot (http://blog.yousoft.ru)');
  10. $data = curl_exec($ch);
  11. curl_close($ch);
  12. ?>

При этом данные в файле ‘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, чтобы мы могли получить заголовки.

  1. <?php
  2. curl_setopt($ch, CURLOPT_HEADER, true);
  3. ?>

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

  1. <?php
  2. string curl_getinfo ( resource $ch [, int $opt] )
  3. ?>

Нас интересует параметр CURLINFO_HEADER_SIZE.

CURLINFO_HEADER_SIZE — Суммарный размер всех полученных заголовков

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

  1. <?php
  2. $header=substr($data,0,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
  3. $body=substr($data,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
  4. ?>

Теперь необходимо выделить непосредственно сами COOKIES, и сформировать строку для того чтобы можно было передать эти COOKIES в следующем запросе.

  1. <?php
  2. preg_match_all("/Set-Cookie: (.*?)=(.*?);/i",$header,$res);
  3. $cookie='';
  4. foreach ($res[1] as $key => $value) {
  5.  //Здесь можно провести любую обработку COOKIES
  6.  $cookie.= $value.'='.$res[2][$key].'; ';
  7. };
  8. ?>

Для того, чтобы CURL передавал COOKIES при запросе нужно их установить. Для этого используем свойство CURLOPT_COOKIE.

CURLOPT_COOKIE — Содержимое заголовка «Cookie: «, который будет отправлен с HTTP запросом.

А, теперь совместим все вместе:

  1. <?php
  2. $cookie='';
  3. $ch = curl_init();
  4. curl_setopt($ch, CURLOPT_URL, 'http://blog.yousoft.ru/');
  5. curl_setopt($ch, CURLOPT_HEADER, true);
  6. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  7. curl_setopt($ch, CURLOPT_COOKIE,$cookie);
  8. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
  9. curl_setopt($ch, CURLOPT_USERAGENT, 'PHP Bot (http://blog.yousoft.ru)');
  10. $data = curl_exec($ch);
  11. $header=substr($data,0,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
  12. $body=substr($data,curl_getinfo($ch,CURLINFO_HEADER_SIZE));
  13. preg_match_all("/Set-Cookie: (.*?)=(.*?);/i",$header,$res);
  14. $cookie='';
  15. foreach ($res[1] as $key => $value) {
  16.  $cookie.= $value.'='.$res[2][$key].'; ';
  17. };
  18. curl_close($ch);
  19. ?>

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

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

Похожие записи:

Tags:

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

  1. Oleg:

    Очень интересная и полезная статья! Спасибо)

  2. Пожалуйста, рад что это интересно не только мне.

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

  4. Orme:

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

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

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

  6. T012:

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

  7. я дурак.
    объясните магию строки:
    preg_match_all(«/Set-Cookie: (.*?)=(.*?);/i»,$header,$res);

    спасибо

  8. сделал так, но полученые кукис не устанавлюваются

  9. Anton Panfilov:

    В 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

  10. А ещё регулярка не найдет, если куки передали так:
    Set-Cookie: a=b;c=d;f=aa

  11. андрей:

    Спасибо. Помог второй вариант обмануть хитрые противоскачиватели

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

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

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

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

  15. Влад:

    2 Кирилл
    Наверное нужно адрес писать не watch.do , а watch.do/login

  16. Replikon:

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

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

  17. Nik:

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

  18. Думаю лучше использовать темповый путь что-то вроде tempnam(«/tmp», «curlcookie»);

  19. VarrkaN:

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

    Зачем?

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

    Делал так:

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

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

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

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

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

  21. andre_h:

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

Leave a Reply