пятница, 7 мая 2010 г.

Получение данных из Google Reader с помощью cURL

Получение данных из Google Reader с помощью cURL

1 декабря, 2009
google reader curl logo

В этой статье я продолжу тему использования cURL. Мы попробуем с помощью этой утилиты войти (аутентифицироваться) и получить список тегов из Google Reader.

Сразу объясню, в чем сложность работы с этим сервисом. Дело в том, что он использует немного необычный способ передачи cookie файлов и из-за этого усложняется аутентификация.

Когда вы заполняете форму входа и отправляете запрос, на большинстве сайтов они в ответ передают страницу и в заголовках cookie файлы. Эти файлы автоматически сохраняются (cURL'ом или браузером) и вы можете использовать их в дальнейших запросах.

Но аутентификация на Google выполняется иначе.

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

Когда вы заходите в Google Reader с помощью браузера, все эти операции выполняются JS-скриптами.

В cURL поддержка JS не входит, поэтому все придется делать ручками ;)

Тут я хочу сделать небольшое отступление.

Во-первых, насколько я знаю, на данных момент API для Google Reader нет. Поэтому все примеры из этой статьи в какой-то момент можут просто перестать работать. Для этого достаточно чтобы разработчики Reader'а совсем чуть-чуть изменили протокол.

Во-вторых, основным источником информации является неофициальный GoogleReaderAPI. Учтите, что статья была написана в 2007, и с тех пор протокол успел немного измениться, поэтому почитать комментарии очень не вредно. В них, кстати, есть пример, который я взял за основу для этой статьи.

Теперь взгляните на сам скрипт

  1. $login = 'ваш_логин';
  2. $pass = 'ваш_пароль';
  3.  
  4. $pathToCurl = 'path/to/curl';
  5. $authData = array();
  6. //получаем SID
  7. exec($pathToCurl.'curl https://www.google.com/accounts/ClientLogin -d Email='.$login.' -d Passwd='.$pass.' -d source=Google-cURL-Example -d service=reader -k', $authData);
  8.  
  9. //запрашиваем T token
  10. $tToken = exec($pathToCurl.'curl -s -X GET http://www.google.com/reader/api/0/token –header "Cookie: '.$authData[0].'"');
  11.  
  12. $feedTags = array();
  13. exec($pathToCurl.'curl -s -X GET http://www.google.com/reader/api/0/tag/list?output=json –header "Cookie: '.$authData[0].'; T='.$tToken.'"', $feedTags);
  14.  
  15. $jsonStr = ";
  16. foreach ($feedTags as $str) {
  17.         $jsonStr .= $str;
  18. }
  19.  
  20. $fTags = json_decode($jsonStr);
  21.  
  22. var_dump($fTags);

Обратите внимание, я сделал два примера (второй листинг – в конце статьи). В первом cURL запускается с помощью функции exec, во втором – используется расширение PHP для работы с cURL.

По-идее второй вариант должен был получиться проще, но оказалось, наоборот :) К тому же, первый вариант проще переделать для использования с другими языками. В общем, выбирайте тот, который вам больше нравиться.

Теперь разберем, как это работает.

1) Мы отправляем запрос с логином и паролем. В ответ приходят данные, которые содержат так называемый SID идентификатор. Его мы должны использовать во всех последующих запросах.

2) Находим SID и отправляем запрос на получение T token. Это еще один идентификатор и его тоже нужно присоединять к последующим запросам вместе с SID.

3) Отправляем запрос на получение списка тегов (или других данных).

Теперь взгляните, как передаются SID и T token (строки 10 и 13). Мы используем ключ --header, после которого идут наши cookie (Cookie: ...). Т.е. мы их не сохраняем на жесткий диск, а сразу вставляем в запрос.
Формат такой
Cookie: par1=val1; par2=val2; ...

Кроме того, обратите внимание, что в первом запросе (строка 7) использован параметр -k. Он отключает проверку SSL сертификатов.

Список тегов я вывел просто с помощью var_dump.

Теперь посмотрите на этот же скрипт, написанный с использованием PHP библиотеки.

  1. $login = 'ваш_логин';
  2. $pass = 'ваш_пароль';
  3.  
  4. //адреса страниц, которые нам нужны
  5. //$authUrl и $tokenUrl – для аутентификации
  6. //$getTagsUrl – получение списка тегов
  7.  
  8. $agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5';
  9.  
  10. //массив с данными для аутентификации
  11. $loginData = array();
  12. $loginData['service'] = 'reader';
  13. $loginData['Email'] = $login;
  14. $loginData['Passwd'] = $pass;
  15. $loginData['source'] = $agent;
  16. $loginData['continue'] = 'http://www.google.com/';
  17.  
  18. //настраиваем curl
  19. $ch = curl_init();
  20. curl_setopt($ch, CURLOPT_URL, $authUrl);
  21. curl_setopt($ch, CURLOPT_STDERR, $el);
  22. curl_setopt($ch, CURLOPT_USERAGENT, $agent);
  23. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  24. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
  25. curl_setopt($ch, CURLOPT_POST, 1);
  26. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($loginData));
  27. //настройка SSL
  28. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
  29. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
  30.  
  31. //получаем данные…
  32. $data = curl_exec($ch);
  33. //… и находим в них SID
  34. $kv = explode("\n",$data);
  35. $authData = array();
  36. foreach ($kv as $str) {
  37.         if (!empty($str)) {
  38.                 $data = explode("=", $str);
  39.                 $authData[$data[0]] = $data[1];
  40.         }
  41. }
  42.  
  43. //получаем T token
  44. curl_setopt($ch, CURLOPT_COOKIE, 'SID='.$authData['SID']);
  45. curl_setopt($ch, CURLOPT_POST, 0);
  46. curl_setopt($ch, CURLOPT_URL, $tokenUrl);
  47. $tToken = curl_exec($ch);
  48.  
  49. //получаем список тегов в формате JSON
  50. curl_setopt($ch, CURLOPT_URL, $getTagsUrl);
  51. curl_setopt($ch, CURLOPT_COOKIE, 'SID='.$authData['SID'].'; T='.$tToken);
  52. $tags = curl_exec($ch);
  53.  
  54. curl_close($ch);
  55.  
  56. var_dump(json_decode($tags));

В принципе, все очень похоже, только параметры запроса указываются с помощью функции curl_setopt.

Правда, тут нужно быть очень внимательным.
Первый запрос уходит методом POST, а следующие два – методом GET (строки 28 и 48). Если забудете изменить – получите ошибку.

Установка cookie выполняется с помощью
curl_setopt($ch, CURLOPT_COOKIE, ...);
в третьем параметре передается строка с данными (в формате параметр=значение, т.е. точно также как и в первом примере).

Как видите, не со всеми сайтами легко работать с помощью cURL :) Кстати, в качестве упражнения, попробуйте firebug'ом проанализировать протокол Google Reader. Думаю, вы быстро убедитесь, что это не так просто сделать.

Комментариев нет:

Отправить комментарий