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

Владимир | | PHP, Web разработка.

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

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

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

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

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

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

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

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

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

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

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

$login = 'ваш_логин';
$pass = 'ваш_пароль';

$pathToCurl = 'path/to/curl';
$authData = array();
//получаем SID
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);

//запрашиваем T token
$tToken = exec($pathToCurl.'curl -s -X GET http://www.google.com/reader/api/0/token --header "Cookie: '.$authData[0].'"');

$feedTags = array();
exec($pathToCurl.'curl -s -X GET http://www.google.com/reader/api/0/tag/list?output=json --header "Cookie: '.$authData[0].'; T='.$tToken.'"', $feedTags);

$jsonStr = ''; foreach ($feedTags as $str) { $jsonStr .= $str; } $fTags = json_decode($jsonStr); 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 библиотеки.

$login = 'ваш_логин';
$pass = 'ваш_пароль';

//адреса страниц, которые нам нужны
//$authUrl и $tokenUrl - для аутентификации
//$getTagsUrl - получение списка тегов
$authUrl = 'https://www.google.com/accounts/ClientLogin';
$tokenUrl = 'http://www.google.com/reader/api/0/token';
$getTagsUrl = 'http://www.google.com/reader/api/0/tag/list?output=json';

$agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5';

//массив с данными для аутентификации
$loginData = array();
$loginData['service'] = 'reader';
$loginData['Email'] = $login;
$loginData['Passwd'] = $pass;
$loginData['source'] = $agent;
$loginData['continue'] = 'http://www.google.com/';

//настраиваем curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $authUrl);
curl_setopt($ch, CURLOPT_STDERR, $el);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($loginData));
//настройка SSL
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);

//получаем данные...
$data = curl_exec($ch);
//... и находим в них SID
$kv = explode("\n",$data);
$authData = array();
foreach ($kv as $str) {
        if (!empty($str)) {
                $data = explode("=", $str);
                $authData[$data[0]] = $data[1];
        }
}

//получаем T token
curl_setopt($ch, CURLOPT_COOKIE, 'SID='.$authData['SID']);
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_URL, $tokenUrl);
$tToken = curl_exec($ch);

//получаем список тегов в формате JSON
curl_setopt($ch, CURLOPT_URL, $getTagsUrl);
curl_setopt($ch, CURLOPT_COOKIE, 'SID='.$authData['SID'].'; T='.$tToken);
$tags = curl_exec($ch);

curl_close($ch);

var_dump(json_decode($tags));

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

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

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

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

Если есть вопросы или замечания, пишите, обсудим!

Постовой

Занимаемся бухгалтерскими услугами, стоимость от 10000 р. в месяц