Пишем свой рейтинг популярных записей русскоязычных блогов на базе Яндекс.API, часть 1
Автор: Nayjest Категория: phpЖил-был в составе поиска по блогам Яндекса рейтинг популярных записей, который для многих был такой себе ежедневной газеткой. Но решили в Яндексе его закрыть да предоставили API, чтобы каждый желающий мог сделать свой рейтинг популярных записей по блогам, чем мы собственно сегодня и займемся. Писать будем на PHP.
Итак, для начала ознакомимся с API статистики записей Поиска по блогам.
Тут все просто, мы имеем RSS ленту статистики записей по блогам за последние 24 часа, разбитую на страницы по 50 записей.
На первой странице выводятся самые свежие записи. Номер страницы, которую нам нужно получить задается параметром p=<номер страницы> в URL адресе, по которому мы обращаемся к API, например: http://blogs.yandex.ru/entriesapi?p=1.
Перейдите по ссылке выше и посмотрите на исходный код этой страницы (Вид->просмотреть источник или Ctrl+U, если у вас FireFox/Opera/Chrome). Мы видим обычный XML документ, который будем читать и анализировать с помощью PHP. Нас интересуют информация о записях, находящаяся внутри тегов <item>. Названия вложенных элементов говорят сами за себя, это:
- author – ссылка на блог/страницу автора;
- description – короткое описание (обычно пусто);
- link – ссылка на пост;
- pubDate – дата и время публикации;
- title – заголовок поста;
- yablogs:commenters – количество разных русскоязычных комментаторов у записи за все время ее существования;
- yablogs:commenters24 – количество разных русскоязычных комментаторов у записи;
- yablogs:comments – общее количество комментариев к записи за все время ее существования;
- yablogs:comments24 – количество комментариев к записи за последние 24 часа;
- yablogs:links – общее количество ссылок на запись за все время ее существования;
- yablogs:links24 – количество ссылок на запись за последние 24 часа;
- yablogs:links24weight – взвешенное количество ссылок на запись за последние 24 часа(с отфильтрованными накрутками и спамными ссылками);
- yablogs:linksweight – общее взвешенное количество ссылок на запись (с отфильтрованными накрутками и спамными ссылками);
- yablogs:visits24 – примерное количество посетителей записи за последние 24 часа;
- yablogs:ppb_username – имя (nickname) автора поста.
Ну что ж, читать такие записи мы научились, теперь давайте научим читать их наш скрипт.
Для начала нужно определиться с инструментом для работы с XML. В PHP manual есть просто таки огромный раздел XML manipulation, где вы можете найти массу различных средств для работы с XML документами. Одним из самых простых, удобных и в то же время мощных решений является расширение SimpleXML, которое поставляется с PHP начиная с 5-й версии и включено по умолчанию. С ним мы и будем работать. Поверьте мне, это действительно очень хороший инструмент, позволяющий просто и удобно работать с XML документами. Продемонстрирую это:
$xml = simplexml_load_file('http://blogs.yandex.ru/entriesapi');
echo '<b>Это заголовок канала:</b> ',
$xml->channel->title, '<br>',
'<b>А это заголовок последнего поста:</b> ',
$xml->channel->item[0]->title, '<br>',
'<b>Время публикации последнего поста: </b> ',
$xml->channel->item[0]->pubDate;
Думаю, тут все понятно: в первой строке мы загружаем первую страницу ленты популярных записей в переменную $xml (функция simplexml_load_file возвращает экземпляр класса SimpleXMLElement), которую далее можем интерпретировать как объект, соответствующий нашему XML документу, что мы собственно и делаем.
Если мы обращаемся к произвольному полю такого объекта, выполняется поиск дочернего элемента XML дерева с именем, соответствующим имени запрошенного поля и если такой элемент найден, возвращается объект, являющийся также экземпляром класса SimpleXMLElement, или массив таких объектов.
Благодаря такой логике работы мы можем выполнять цепочки запросов вида: $xml->someElement->children->childrenOfChildren.
Обратите внимание, что элементов item в нашем XML документе много, поэтому $xml->channel->item возвращает не один объект, а массив объектов, предоставляющих доступ к этим элементам. В примере мы обратились к самому первому в документе элементу item по индексу [0], и вывели его заголовок и дату публикации на экран (в браузер).
Альтернативный способ получить нужную ветвь XML документа в SimpleXML — это использование XPath, языка запросов к элементам XML дерева. В классе SimpleXMLElement для этого имеется метод xpath(string $path), возвращающий массив экземпляров класса SimpleXMLElement или FALSE в случае ошибки.
Пример использования XPath:
$items=$xml->xpath('channel/item');
Чтобы получить аналогичный набор элементов без XPath, нужно выполнить:
$items=$xml->channel->item;
Использование XPath или цепочек вызовов полей — это дело вкуса, в нашем случае мы будем использовать XPath, чтобы обратиться к элементам типа yablogs:links, где есть символ «:», так как он мешает интерпретировать эти элементы как поля объекта в PHP.
Ну давайте уже что-нибудь сделаем. Например функцию, получающую информацию о всех записях за 24 часа. Собственно, вот:
- define ('MAX_PAGES',200);
- function load_all() {
- $all_items=array();
- for ($i=1; true;$i++) {
- $xml = simplexml_load_file('http://blogs.yandex.ru/entriesapi?p=' . $i);
- $items=$xml->xpath('channel/item');
- if (empty($items)) {
- break;
- }
- $all_items=array_merge($all_items,$items);
- if ($i>=MAX_PAGES) break;
- }
- return $all_items;
- }
Такая функция конечно же будет работать очень медленно и скорее всего упрется в ограничение на время выполнения php скриптов: по умолчанию — 30 секунд, поэтому полученные данные нужно обязательно кэшировать, а само их получение выполнять не при открытии страницы, а через планировщик задач crontab. Мы будем сохранять полученную информацию в базу данных, использовать будем MySQL, но об этом в следующей части, а пока вернемся к работе с XML.
Давайте уже в этом уроке соберем наш рейтинг популярных записей русскоязычных блогов с минимальным функционалом и отложим на потом кэширование, расширение функционала, придание ООП’шности и MVC’шности нашему коду.
Чтобы долго и нудно не ждать результата выполнения функции load_all(), давайте зададим ей ограничение: будем обрабатывать только первые 4 страницы RSS ленты, выдаваемой Яндексом. Специально для этого я ввел константу MAX_PAGES, заменяем значение 200 в первой строчке на 4.
Наш рейтинг должен уметь сортировать записи по количеству комментариев, количеству ссылок и количеству посещений. Мы уже имеем функцию, с помощью которой можем получить список записей. Значит задача состоит в сортировке этого списка.
Если бы мы заносили информацию о всех записях в базу данных скриптом, вызываемым через планировщик задач, а при выдаче информации пользователю, брали бы ее из БД, то мы бы воспользовались возможностями SQL для сортировки, но это мы будем делать во второй части урока, а сейчас сделаем по-быстрому сортировку средствами PHP.
Поможет нам в этом стандартная функция PHP usort, позволяющая сортировать массивы с использованием своей функции для сравнения элементов массива.
Элементами массива у нас являются экземпляры класса SimpleXMLElement, инициализированные элементами XML дерева <item>.
Рассмотрим, как мы можем получить к примеру количество комментариев записи:
- $xml = simplexml_load_file('http://blogs.yandex.ru/entriesapi');
- $item=$xml->channel->item[12];//Получаем какой-нибуть XML элемент item, например 13-й.
- $comments_arr=$item->xpath('yablogs:comments');//получаем массив объектов
- $comments_obj=$comments_arr[ 0];//объект у нас должен быть один, это мы знаем
- $comments=(int)$comments_obj;//приводим его тип к целочисленному (int), чтобы можно было выполнить сравнение
А теперь можно написать и функцию сравнения, причем универсальную.
- $cmp='yablogs:comments';//по этому параметру сравниваем,
- //к функции сравнения при использовании в usort есть требование:
- //она должна принимать два только параметра,
- //соответствующие сравниваемым элементам массива,
- //поэтому делаем $cmp просто глобальной переменной
- function cmp($a, $b)
- {
- global $cmp;
- $a=$a->xpath($cmp);
- $b=$b->xpath($cmp);
- $a=(int)$a[0];
- $b=(int)$b[0];
- if ($a == $b) {
- return 0;
- }
- return ($a > $b) ? -1 : 1;
- }
У нас будет функция sort_by, в которую будем передавать ссылку на массив и строку, соответствующую XML элементу, по которому будем сортировать (критерий сравнения). sort_by в свою очередь будеть вызывать стандартную функцию usort, передавая ей ссылку на массив и присваивать глобальной переменной $cmp критерий сравнения.
- function sort_by($sort_by,$i)
- {
- global $cmp;
- $cmp=$sort_by;
- usort($i,'cmp');
- }
Почти готово, теперь мы можем к примеру вывести отсортированные по количеству комментариев записи вот так:
- $items=load_all();
- sort_by('yablogs:comments',&$items);
- foreach ($items as $item) {
- $comments=$item->xpath('yablogs:comments');
- $links=$item->xpath('yablogs:links');
- $visits=$item->xpath('yablogs:visits24');
- echo "<a href='$item->link'>$item->title</a><br>",
- "Комментариев: $comments[0]<br>",
- "Ссылок: $links[0]<br>",
- "Просмотров: $visits[0]<hr>";
- }
Как именно сортировать наш список, будем передавать параметром URI sort_by, который будет доступен в php как $_GET['sort_by']. Создадим три ссылки для разных типов сортировки, для этого перед тегом <?php, обозначающим начало php кода, пишем:
- <div style="text-align:center;">
- <a href="index.php/?sort_by=comments">Самые комментируемые</a>
- <a href="index.php/?sort_by=visits24">Самые посещаемые</a>
- <a href="index.php/?sort_by=links">Самые цитируемые</a>
- </div>
Нам осталось только получить в PHP критерий сортировки и отсортировать все соответствующим образом. Для этого строку с sort_by(‘yablogs:comments’,&$items) заменяем на это:
- if (isset($_GET['sort_by'])){
- $crit=$_GET['sort_by'];
- }else{
- $crit='comments';
- }
- sort_by('yablogs:' . $crit ,&$items);
И напоследок добавим немного оформления с помощью CSS, чтобы наш рейтинг смотрелся получше:
- <style>
- div{padding:20px; background-color:#EEE;}
- hr{border:none; border-bottom:1px dashed yellow;}
- </style>
Исходник того, что мы сделали вы можете скачать здесь: http://www.nayjest.ru/userfiles/yabdex.blograting.by.nayjest.zip
В следующих уроках я расскажу, как сделать из этого полноценный веб-сервис, где все будет ООП’шненько, будет работа с БД, архитектура MVC, валидный HTML, кэширование, может даже AJAX и вообще все, что захотите (предлагайте в комментариях!).
Надеюсь, было интересно и полезно. Чтобы не пропустить следующие уроки, подписывайтесь на мой RSS, follow me on Twitter. Спасибо за внимание, жду ваших комментариев!


Декабрь 18th, 2009 - 15:32
Пишем свой рейтинг популярных записей русскоязычных блогов на базе Яндекс.API, часть 1 « Блог Виталия Степаненка…
Thank you for submitting this cool story – Trackback from progg.ru…
Декабрь 19th, 2009 - 22:49
Забавно что вы описали даже те параметры записей, которых нет в официальной документации, ну это уже недостатки Яндекса :)
Январь 4th, 2010 - 15:56
Попытался сделать по данному мануалу, только видимо где-то допустил ошибку. При открытий сайта на опере почему то появляются крякозябры.
Сейчас буду заного изучать инструкцию =)
Январь 4th, 2010 - 17:26
EHT, а какую кодировку Вы используете? Тут нужно правильно настроить веб-сервер. Я советую использовать UTF-8, убедитесь, что ваш файл с исходниками сохранен в UTF-8 (если нет — пересохраните в этой кодировке), и настройте ваш веб-сервер, чтобы он выдавал документы в нужной вам кодировке (у вас Апач?), попробуйте в файле .htaccess прописать AddDefaultCharset utf-8.
Кроме этого у нас в примере ниразу не валидный html, можете добавить нужные секции (html, head, body) и указать кодировку страницы соответствующим meta-тегом.
Январь 5th, 2010 - 22:52
А это может зависеть от кодировки на сервере который предоставляет хостинг компания?
Январь 5th, 2010 - 23:11
To EHT: ну да, кодировка задана на вашем сервере, но Вы можете ее переопределить, например через .htaccess, как я писал выше, чтобы не лезть в настройки веб-сервера (к которым у вас скорее всего доступа нет, если вы используете shared hosting).
Январь 10th, 2010 - 03:20
А мне пост понрвился. Добавил в букмарки. (не спам)
Январь 12th, 2010 - 19:07
Хорошо написал. Так держать!!! :)
Январь 28th, 2010 - 02:52
Олололо! Теперь интернетам песда. Через пару неделек когда школьнеги заполонят все своими рейтингами, начинай песать мануал, как создать рейтинг рейтингов блогов и так далее, пока все не скончаются от рекурсии.
Даешь смерть через рекурсию!
Февраль 16th, 2010 - 21:48
Школьнеги тоже имеют право на то, что б в интернете всякий бред писать, так что не умничай:)
Март 8th, 2010 - 09:05
Офигительно! Не просто занес себе в закладки, но и скопировал весь пост целиком (вдруг сайт будет недоступен, а такая ценная инфа – на вес золота).
Март 18th, 2010 - 16:14
Вы золотой человек, добавил блог в закладки и подписался по rss. Запись очень полезная.
Март 18th, 2010 - 19:14
Давно пользуюсь такой фичкой! Довольно таки интерестная функция. Правда с кодировкой вначале были проблемы, долго разбирался. Но потом заработало!
Март 20th, 2010 - 01:57
ДОВОЛЬНО широко расскрыта статья. На мой взгляд Яндекс только начал работу в этой сфере и поддержания своего приложения, но в данной сфере ведущим поставщиком услуг api-приложений, в том числе и на блоги является google.
Март 23rd, 2010 - 14:51
Замечательно расжевано, будет время попробую)) Сэнкс)) Ждем продолжения)
Март 23rd, 2010 - 20:16
С первого разар опять не получается (((
Плюнул. Буду пробовать завтра! ))
Март 24th, 2010 - 17:26
Кульная статья получилась)) Сейчас немного переварю и буду пробовать шаг за шагом.
Март 26th, 2010 - 21:39
Спасибо за информацию, свой список – это же круто! Людей можно привлечь!
Март 27th, 2010 - 23:35
Топ записей Яндекса, который задумывался как зеркало блогосферы, стал медийной площадкой. Многие блогеры использовали социальную накрутку, прося друзей поставить ссылки на свои записи и тем самым вывести их в топ.
Март 28th, 2010 - 16:12
2Mashara что правда? такие банальные вещи всем понятны, есть интереснее мысль что государство повлияло на яндекс из за отражения недовольства населения
Март 29th, 2010 - 14:53
Спасибо, пытался раньше сам подобную штуку сделать, но не получилось. Благодаря этим функциям, переделал свой скрипт ;)
Апрель 3rd, 2010 - 21:58
Это же надо так скурпулёзно и точно всё описать. У меня бы в жизни бы терпения не хватило. И всё ради чего, я вас спрашиваю? А всё ради увеличения трафика.
Апрель 5th, 2010 - 12:21
Благодарю за статью. Проанализировал и исправил свой скрипт, теперь все работает!
Апрель 19th, 2010 - 20:07
Я извиняюсь, а зачем это надо?
Апрель 23rd, 2010 - 23:47
Ну вот – раскрыли все их карты. На всякий случай сохранил, может быть, в ближайтее время опробую.
Апрель 25th, 2010 - 18:38
Странно,искал на форумах php-ккодеров, а нашёл здесь случайно как это делается. Зачотно
Апрель 27th, 2010 - 11:15
Спасибо, крайне полезная статья. Как то раньше не доводилось соединять два в одно…
Май 4th, 2010 - 15:18
Спасибо! Хороший мануальчик по API))) То, что надо))
Май 4th, 2010 - 22:52
Спасибо за очередную хорошую статью. Очень нравится манера написания!
Май 8th, 2010 - 11:33
интересно было бы с вами лично пообщаться )) вы в аське бываете? или в скайпе?…
Май 9th, 2010 - 20:08
Я колнечно может мужу – но вам бы поработать над дизайном блога – мелко все и блекло
Май 12th, 2010 - 21:36
Яндекс.XML предоставляет 1000 запросов с 1 ip, а здесь какие лимиты, что то я не заметил в посте.
Май 12th, 2010 - 23:32
да интересненько нуно бут попробовать :)
Май 13th, 2010 - 12:18
Настоящим программистам это будет интерестно )
Май 22nd, 2010 - 19:01
николай и пользователям тоже интересно. ведь они учатся это понимать…
Май 25th, 2010 - 23:37
Не знаю какая польза от рейтингов, мне гораздо приятнее виделть статистику посещений моего блога
Май 26th, 2010 - 13:49
начал делать, кончилось пиво, забил =)
не мое это)
Май 27th, 2010 - 02:31
@rezident Свой рейтинг нужен только для привлечения новых посетителей (ИМХО).
По-моему идея очень даже неплохая, сделать у себя на блоге свой собственный рейтинг блогов, обозвать его как-нибудь красиво, и будет счастье.
Правда я технарь хреновый, но думаю, куча времени, вот эта инструкция, форумы и дикое желание позволит создать собственный рейтинг блогов, чтобы можно было в нём регистрироваться, по категориям и соревноваться с другими. Короче классический рейтинг. Как вы думаете, можно такое замутить? Или это нереально?
Май 28th, 2010 - 23:17
Здорово что вы описали даже те параметры записей, которых нет в официальной документации, ну это уже недостатки Яндекса :)
Май 30th, 2010 - 19:23
А можно где-нибудь посмотреть реализацию Вашего программного кода. Именно в действии?? На вашем сайте не нашел, если что ткните носом…
Июнь 2nd, 2010 - 11:39
Теперь все работает, благодарю за статью. Проанализировал и исправил свои скрипты
Июнь 2nd, 2010 - 14:28
Автору огромное спасибо и глубочайший респект! Нашел ваш скрипт очень полезным!
Июнь 7th, 2010 - 10:32
Скиньте пожалуйста на мыло ваш скрипт. Буду очень благодарен
Июнь 8th, 2010 - 08:06
хороший скрипт , спасибо!
Июнь 11th, 2010 - 13:01
Кажется всё у Яндекса работает. Глючит, но работает :) Попиарились они, а может услышали воззвания блоггеров.
Июнь 14th, 2010 - 15:25
Работает на 100%
Июнь 15th, 2010 - 09:45
Спасибо за хорошую статью! главное что все работает
Июнь 15th, 2010 - 18:38
Руки чешутся где-нибудь это применить. :))
Июнь 16th, 2010 - 11:49
Кстати, хорошая штука, которая пригодится. Надо знакомому программисту отдать, пусть что-нибудь полезное сваляет.
Июнь 20th, 2010 - 11:33
Да, работоспособность подтверждаю. Ждем продолжения)
Июнь 20th, 2010 - 22:58
Подскажите пожалуйста. Как создать рейтинг определенных блоггеров. Если все перелистывать, не хватает времени. Как быть?
Июнь 21st, 2010 - 23:54
Спасибо! Правда с кодировкой вначале были проблемы, долго разбирался, но потом все ОК.
Июнь 23rd, 2010 - 19:55
спасибо за пост
Июнь 30th, 2010 - 15:47
Довольно полезная информация, спасибо. Надо обязательно попробовать применить на практике
Июль 11th, 2010 - 18:46
На мой взгляд не самое лучшее решение.
Июль 12th, 2010 - 01:55
+1
Июль 13th, 2010 - 13:40
Как знать, может оно и так, но попробовать все же стоит
Июль 14th, 2010 - 12:13
За пост спасибо, но что за фишка называть свой блог своим именем и фамилией. А если ваша фамилия бала бы Педиков вы назвали свой блог Василий Педиков? Не обижайтесь пожалуйста
Июль 15th, 2010 - 17:42
А можно такой вопрос: нафик он вообще нужен этот рейтинг?
Июль 23rd, 2010 - 15:50
Хорошая статья!
Июль 24th, 2010 - 20:16
Спасибо. Пишешь очень подробно и с примерами – что мне очень нравится.
Подписался, будем читать.)))
Июль 26th, 2010 - 02:25
Однако, очень полезная статья! Думаю, что у меня обязательно в скором времени появится такой свобственный рейтинг. Мне очень не хватает этой функции…)
Июль 26th, 2010 - 09:56
желаю успехов
Июль 29th, 2010 - 13:00
Полезно, будем пользоваться этими API, спасибо за инфу.
Сейчас себе подобный скриптик наваяю.
Август 5th, 2010 - 13:27
Вроде сделал все как сказано, но не работает..
Август 6th, 2010 - 01:48
Что-то моих знаний чтобы с этим разобраться пока не хватает, но сам скрипт однозначно мегаполезный. Очень хочется иметь! Что делать-то? Где почитать литературу по этой тематике, чтобы со скриптом таки разобралась?
Август 7th, 2010 - 18:39
Число сайтов с каждым днем растет, число веб-мастеров тоже, желающих заработать на сайте становиться больше, что такое SEO по моему знают уже в начальных классах. Вопрос: Куда катится Мир??? Ответ: Выживут те, кто научился приспосабливаться – закон Естественного отбора Чарльза Дарвина
Август 10th, 2010 - 22:53
Чтоб заработать в нэте надо что то делать. Прошли те времена когда тут текли реки халявы.
Август 16th, 2010 - 23:50
Не думал что такое простое решение, спс
Август 20th, 2010 - 03:17
попробуем эту штукенцию
Сентябрь 1st, 2010 - 13:06
Я думал такую штуку создать будет посложнее. А на каких движках тестили?