«Мониторинг активности групп VK. Обрабатываем данные на VKScript»
Раздел: Социальные сети
Столкнулся с задачей мониторинга активности пользователей всем известной социальной сети. Передо мной стояла задача собирать данные о количестве пользователей, находящихся онлайн в определенной группе или сообществе.ИнструментыПоскольку сам я занимаюсь веб-разработкой, то инструменты мной использовались такие
Объясню свой выбор — Vk API — дело в том, что получить количество пользователей онлайн можно и без API, а спарсив страницу поиска по пользователям с фильтром сообщества и метки онлайн, однако я предпочел не возится с авторизацией и разбором тегов, а применить программный интерфейс. АрхитектураРеализацию условно можно разделить на 2 части. Первая — скрипт, который на id группы находит количество пользователей онлайн и записывает его в БД. Вторая — админка, позволяющая добавлять новый группы для мониторинга и просматривать статистику по уже добавленным группам. Что бы статистика была актуальна, необходимо как можно чаще мониторить состояние группы в текущий момент времени. Скрипт стоит повесить в Cron, пусть он у нас вызывается каждых 5 минут. Обзор Vk APIЕсли с админкой все более-менее понятно, то вот со скриптом сбора статистики не совсем. Ознакомившись с методами, предоставляемыми API, прихожу к первому решению. Первое решение (неверное)С помощью методов groups.getMembers, users.get получаем список участников группы и их статус — онлайн или оффлайн. Далее считаем сколько пользователей онлайн. Все просто. Однако кажущаяся простота в результате приносит ряд проблем. Все бы хорошо, если у Вас группы маленькой численностью (до 1000 человек). В противном случае упираемся в ограничения API — за один раз можно получить информацию только о 1000 пользователей. Что нам это ограничение — можно же вызывать метод в цикле, но нет. Производить вызовы API разрешено не чаще 3 запросов в секунду. Посчитаем примерное количество запросов которое понадобится. Возьмем сообщество habrahabr Vk. Оно насчитывает более 40.000 пользователей, следовательно нам понадобится ~40 запросов чтобы получить членов сообщества и 40 запросов — их статус. Отправляемся искать новое решение. Второе решение (верное)Обнаруживаем в документации метод execute Универсальный метод, который позволяет запускать последовательность других методов, сохраняя и фильтруя промежуточные результаты. Принимает он на вход строку с кодом написанным на так называемом VKScript (похож на javascript). Проблема лишь в том, что вменяемая документация по этому методу и самому языку отсутствует. Вероятно решение найдено, так что можно углубится в изучение API Vk и VKScript в частности. Работа с APIСкачиваем класс для работы с API, предлагаемый разработчиками. Я привел его только к более приемлемому виду, чтобы он вписался в coding style применяемый в Zend Framework. Класс Api
Аутентификацию и авторизацию я описывать не буду, так как она осуществляется через OAuth, много информации в рунете, да и на странице Vk API. Осуществим пробный вызов к API — получим первые 20 постов в группе habrahabr
Сейчас сделаем тоже самое, только через метод execute
В итоге получаем один и тот же результат. Одно что плохо — это то, что мы смешали код VKScript и PHP. Выглядит это очень плохо. Займемся рефакторингом. Было бы неплохо, чтобы каждый скрипт хранился в отдельном файле и вызвать его можно было бы одной функцией. Еще необходимо предусмотреть то, что в последствии нам еще понадобится передавать какие-то данные в этот скрипт ( сейчас например owner_id жестко забит в код). Выносим VKScript в отдельные файлыВ корне нашего модуля создадим папку с названием «vkscripts», в нее будем складывать наши скрипты (например getWalls.vks). Пропишем путь к скриптам в config-файле application.ini
Нам нужен класс, который был бы удобен для вызова скриптов, расположенных в этой директории. Воспользуемся возможностями PHP5, а именно магическим методом __call. По названию вызываемого метода мы будем искать скрипт с таким названием. Исходник класса
Итак, давайте что-нибудь сделаем с этим классом. В папку vkscripts кладем файл getWalls.vks с таким содержимым
В контроллере:
Мы получили тот же результат, только налицо существенные плюсы: мы разнесли код в отдельные файлы, сделали его более читабельным, упростили вызов execute. Следующий шаг — добавление возможности передавать параметры в наш скрипт. Воспользуемся для этого неким представлением. В коде VKScript вначале при необходимости что-то получить на вход будем писать так:
А в нашем классе будем перед вызовом api с этим кодом заменять %VAR_NAME% на значение переменной. Допишем наш класс Executor следующим образом Исходник доработанного класса
В контроллере же при необходимости передачи параметром пишем следующее
Что соответственно подставит в наш скрипт вместо %GROUP_ID% и %OFFSET% переданные значения. Вот как выглядит структура модуля Получаем количество пользователей онлайнCуществует ограничение на вызов методов API в execute. Лимит 22 вызова (найден практически). Так же в паутине я не нашел информации о том, что и на другие операторы (например сложение, вычитание ) тоже существуют ограничения, однако они есть. Поскольку если пробегать по массиву пользователей и считать количество онлайн я получал ошибку о превышенном числе операций, то было решено возвращать из execute полный список пользователей, после чего уже на стороне моего сервера считать их количество. Из-за ограничения в числе запросов к API в методе execute нам все равно придется выполнить как минимум 1 запрос на 10.000 участников группы, потому что для обработки 1.000 требуется 2 запроса. Вот скрипт который получился
Немного прокомментирую свой код. Счетчик _acl — для предотвращения ошибки из-за превышения лимита операций с API. users@.online — возвращаем только список значений [0,1,1,0,0,0,1,0,1] онлайн-оффлайн. В контроллере вызываем этот скрипт, последовательно увеличивая offset, пока не пробежимся по всем участникам группы.
Итак протестим и увидим — данные полученные через API почти совпадают с данными с vk.com, возможно эта неточность из-за кешей, или по другой причине, не видной извне. ЗамечанияVKScript не поддерживает функции, операторы инкремента, декремента. ИтогМы разработали инструментарий для работы с API vk.com через метод execute. С помошью его можно разрабатывать приложения сбора статистики и т.д. причем выглядеть это будет очень даже приглядно. Прикрутить к этому всему интерфейс — это уже тривиальная задача. В конце замечу, что другая социальная сеть Facebook предоставляет доступ к исполнению кода, написанного на языке называемом FQL (Facebook Query Language, схож с SQL), у которого возможностей явно побольше чем у VKScript со всеми его ограничениями. СсылкиVK API Метод execute, краткое описание и пример VKScript Facebook Query Language Дата публикации: 2012-11-13 |