Выгрузка всех групп пользователя в вк. Ссылка и id группы Вконтакте
На создание данной статьи я был вдохновлен публикацией «Получение участников сообщества vk.com за считанные секунды» . Моя статья написана новичком и отражает опыт решения одной задачи. Основная цель написания этой статьи для меня - собрать мнения, отзывы и критику примененного подхода от более опытных коллег. Кроме того, надеюсь, что кому-то приведенная здесь информация будет полезна.
Не так давно в одном из тестовых задания на вакансию младшего php-программиста мне попалась простая, но интересная для меня задача.
«Сделайте скрипт на php, который возвращает список id пользователей «ВКонтакте», разделенный символами перевода строки, которые являются мужчинами старше 25 лет и состоят в группе vk.com/habr ».
Доступ к информации из базы «ВКонтакте» осуществляется с использованием VK API. Начинать знакомство с VK API лучше с официальной документации . Для того чтобы вызвать метод API ВКонтакте, необходимо осуществить POST или GET запрос по протоколу HTTPS на URL следующего вида:
Получаем JSON-структуру с общим количеством членов сообщества vk.com/habr и тысячей первых id в списке по умолчанию отсортированном по возрастанию.
По условию задачи нам нужно вывести id пользователей определенного пола и возраста. Очевидный способ - выбирать запросами VK API пользователей группы вместе с их данными о поле и возрасте, а потом в PHP-коде анализировать их и выводить только нужные. Другой возможный способ - метод execute - позволяет в одном запросе передать скрипт на специальном языке VKScript для манипуляции с данными на сервере и вернуть уже обработанные данные. Сразу скажу, что мне не удалось, решить задачу с помощью метода execute. Может быть в комментариях кто-то укажет такое решение.
Пойдем по первому пути. Метод groups.getMembers с помощью значения sex параметра fields может выдавать пол пользователя, но он не выдает возраст. Вместо этого параметр fields имеет поле bdate - дата рождения. Кроме того, в запросах мы выбираем по тысяче пользователей, значит каждый следующий запрос должен выдать следующую тысячу. Для этого есть параметр offset, который показывает с какой позиции начинать выборку. Укажем в запросе еще и версию API.
В итоге запрос будет иметь примерно такой вид: https://api.vk.com/method/groups.getMembers?group_id=habr&offset=0&fields=sex,bdate&version=5.27
Чтобы забирать файл по ссылке, в PHP есть функция file_get_contents() . Она получает контент по ссылке и возвращает его в виде строки. Нужно учесть, что для того, чтобы file_get_contents() понимала протокол HTTPS нужна поддержка openssl в веб-сервере.
Потом полученный JSON-контент можно преобразовать в массив функцией json_decode() . Массив будет содержать и id, и пол. Дата рождения может быть вообще не указана.
Если дата рождения всё же указана, осталось из даты рождения получить возраст.
Даты рождения в bdate хранятся в строках формата ДД.ММ.ГГГГ, если указан год рождения, или ДД.ММ, если год рождения не указан. Чтобы узнать в каком формате строка фактически, я использовал первое, что пришло в голову: count(explode(".", $user_array["bdate"])) равно 2 или 3. Этот способ работает и не думаю, что это самое узкое место скрипта.
Для вычисления возраста по дате рождения нашел формулу hashcode.ru/questions/137939#137940 . Функция strtotime() понимает формат поля bdate.
Проверяем пол и возраст. Если они удовлетворяют условию, выводим id.
Весь код на PHP
// Номер пакета запроса
$packet = 0;
// Размер пакета запроса
$limit = 1000;
do {
// Каждый запрос начинаем там, где остановились в предыдущем запросе.
$offset = $ packet * $limit;
// Выполнение запроса.
// Результат - JSON-файл с общим количеством и данными пользователей.
// Чтобы file_get_contents() работал с https на веб-сервере apache
// должен быть активен модуль openssl.
$contents = file_get_contents("https://api.vk.com/method/groups.getMembers?group_id=habr&offset=$offset&fields=sex,bdate&version=5.27")
// Преобразуем JSON в массив
$members = json_decode($contents, true);
// Данные пользователей хранятся в подмассиве users.
// Каждый элемент users - ассоциированный массив с данными.
foreach ($members["response"]["users"] as $user_array) {
// Если пользователь указал дату рождения и пользователь - мужчина...
if ((isset($user_array["bdate"])) && ($user_array["sex"] == 2)) {
// ... и если в дате рождения три компонента (ДД.ММ.ГГГГ)...
if (count(explode(".", $user_array["bdate"])) == 3) {
// то вычисляем возраст (формулу нашел в интернете)
$age = floor((time()-strtotime($user_array["bdate"]))/(60*60*24*365.25));
// Если возраст нам подходит, выводим id пользователя с переводом строки
if ($age >
";
}
}
}
}
// Переходим на следующий пакет.
$packet++;
} while ($members["response"]["count"] > $offset + $limit);
Этот вариант прекрасно работает на относительно небольших группах, но на группах более 100 тысяч подписчиков скрипт отрабатывает не до конца - в какой-то момент почему-то вываливается ошибка «file_get_contents(...): failed to open stream: Connection timed out in … on line ...». Пробовал увеличивать время выполнения скрипта и таймаут веб-сервера - не помогло. Так и не смог найти закономерность.
Тогда нашелся другой вариант - для загрузки ответа запроса использовать cURL . Чтобы применить такой метод, необходимо установить в ОС библиотеку libcurl, например, в Ubuntu - sudo apt-get install libcurl3
и включить в PHP поддержку cURL, например, в Ubuntu - sudo apt-get install php5-curl
Теперь можно открыть в PHP-скрипте сеанс curl функцией curl_init() , установить параметры соединения (в том числе URL) функцией curl_setopt() и скачивать контент JSON-файлов в строку функцией curl_exec() . Потом следует закрыть сеанс - curl_close() . Остальной код остается без изменений:
Весь код с cURL на PHP
// Номер пакета запроса
$packet = 0;
// Размер пакета запроса
$limit = 1000;
// Инициализируем cURL.
// Для работы с cURL должна быть установлена библиотека libcurl
// и включена поддержка cURL в PHP.
$ch = curl_init();
do {
// Каждый запрос начинаем там, где остановились в предыдущем запросе.
$offset = $ packet * $limit;
// Параметры запроса
curl_setopt($ch, CURLOPT_URL, "https://api.vk.com/method/groups.getMembers?group_id=habr&offset=$offset&fields=sex,bdate&version=5.27");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
// Выполнение запроса.
// Результат - JSON-файл с общим количеством и данными пользователей.
$content = curl_exec ($ch);
$members = json_decode($contents, true);
// Данные пользователей хранятся в подмассиве users.
// Каждый элемент users - ассоциированный массив с данными.
foreach ($members["response"]["users"] as $user_array) {
// Если пользователь указал дату рождения и пользователь - мужчина...
if ((isset($user_array["bdate"])) && ($user_array["sex"] == 2)) {
// ... и если в дате рождения три компонента (ДД.ММ.ГГГГ)...
if (count(explode(".", $user_array["bdate"])) == 3) {
// то вычисляем возраст (формулу нашел в интернете)
$age = floor((time()-strtotime($user_array["bdate"]))/(60*60*24*365.25));
// Если возраст нам подходит, выводим id пользователя с переводом строки
if ($age > 25) {
echo $user_array["uid"] . "
";
}
}
}
}
// Переходим на следующий пакет.
$packet++;
} while ($members["response"]["count"] > $offset + $limit);
// Закрываем cURL
curl_close ($ch);
Как я уже говорил, думаю, возможен подход с методом execute, но мне пока не удалось получить в этом направлении удовлетворительный результат.
P. S. Прошу не думать, что я хочу получить от аудитории «Хабра» решение тестового задания. Вышеприведенные варианты я уже давно отправил и получил ответ. Просто немало времени потратил на эту задачу и хотел бы узнать, в правильном направлении ли я двигался и какие еще подходы можно было бы использовать.
На создание данной статьи я был вдохновлен публикацией . Моя статья написана новичком и отражает опыт решения одной задачи. Основная цель написания этой статьи для меня - собрать мнения, отзывы и критику примененного подхода от более опытных коллег. Кроме того, надеюсь, что кому-то приведенная здесь информация будет полезна.
Не так давно в одном из тестовых задания на вакансию младшего php-программиста мне попалась простая, но интересная для меня задача.
«Сделайте скрипт на php, который возвращает список id пользователей «ВКонтакте», разделенный символами перевода строки, которые являются мужчинами старше 25 лет и состоят в группе vk.com/habr ».
Доступ к информации из базы «ВКонтакте» осуществляется с использованием VK API. Начинать знакомство с VK API лучше с официальной документации . Для того чтобы вызвать метод API ВКонтакте, необходимо осуществить POST или GET запрос по протоколу HTTPS на URL следующего вида:
Получаем JSON-структуру с общим количеством членов сообщества vk.com/habr и тысячей первых id в списке по умолчанию отсортированном по возрастанию.
По условию задачи нам нужно вывести id пользователей определенного пола и возраста. Очевидный способ - выбирать запросами VK API пользователей группы вместе с их данными о поле и возрасте, а потом в PHP-коде анализировать их и выводить только нужные. Другой возможный способ - метод execute - позволяет в одном запросе передать скрипт на специальном языке VKScript для манипуляции с данными на сервере и вернуть уже обработанные данные. Сразу скажу, что мне не удалось, решить задачу с помощью метода execute. Может быть в комментариях кто-то укажет такое решение.
Пойдем по первому пути. Метод groups.getMembers с помощью значения sex параметра fields может выдавать пол пользователя, но он не выдает возраст. Вместо этого параметр fields имеет поле bdate - дата рождения. Кроме того, в запросах мы выбираем по тысяче пользователей, значит каждый следующий запрос должен выдать следующую тысячу. Для этого есть параметр offset, который показывает с какой позиции начинать выборку. Укажем в запросе еще и версию API.
В итоге запрос будет иметь примерно такой вид: https://api.vk.com/method/groups.getMembers?group_id=habr&offset=0&fields=sex,bdate&version=5.27
Чтобы забирать файл по ссылке, в PHP есть функция file_get_contents() . Она получает контент по ссылке и возвращает его в виде строки. Нужно учесть, что для того, чтобы file_get_contents() понимала протокол HTTPS нужна поддержка openssl в веб-сервере.
Потом полученный JSON-контент можно преобразовать в массив функцией json_decode() . Массив будет содержать и id, и пол. Дата рождения может быть вообще не указана.
Если дата рождения всё же указана, осталось из даты рождения получить возраст.
Даты рождения в bdate хранятся в строках формата ДД.ММ.ГГГГ, если указан год рождения, или ДД.ММ, если год рождения не указан. Чтобы узнать в каком формате строка фактически, я использовал первое, что пришло в голову: count(explode(".", $user_array["bdate"])) равно 2 или 3. Этот способ работает и не думаю, что это самое узкое место скрипта.
Для вычисления возраста по дате рождения нашел формулу hashcode.ru/questions/137939#137940 . Функция strtotime() понимает формат поля bdate.
Проверяем пол и возраст. Если они удовлетворяют условию, выводим id.
Весь код на PHP
// Номер пакета запроса
$packet = 0;
// Размер пакета запроса
$limit = 1000;
do {
// Каждый запрос начинаем там, где остановились в предыдущем запросе.
$offset = $ packet * $limit;
// Выполнение запроса.
// Результат - JSON-файл с общим количеством и данными пользователей.
// Чтобы file_get_contents() работал с https на веб-сервере apache
// должен быть активен модуль openssl.
$contents = file_get_contents("https://api.vk.com/method/groups.getMembers?group_id=habr&offset=$offset&fields=sex,bdate&version=5.27")
// Преобразуем JSON в массив
$members = json_decode($contents, true);
// Данные пользователей хранятся в подмассиве users.
// Каждый элемент users - ассоциированный массив с данными.
foreach ($members["response"]["users"] as $user_array) {
// Если пользователь указал дату рождения и пользователь - мужчина...
if ((isset($user_array["bdate"])) && ($user_array["sex"] == 2)) {
// ... и если в дате рождения три компонента (ДД.ММ.ГГГГ)...
if (count(explode(".", $user_array["bdate"])) == 3) {
// то вычисляем возраст (формулу нашел в интернете)
$age = floor((time()-strtotime($user_array["bdate"]))/(60*60*24*365.25));
// Если возраст нам подходит, выводим id пользователя с переводом строки
if ($age >
";
}
}
}
}
// Переходим на следующий пакет.
$packet++;
} while ($members["response"]["count"] > $offset + $limit);
Этот вариант прекрасно работает на относительно небольших группах, но на группах более 100 тысяч подписчиков скрипт отрабатывает не до конца - в какой-то момент почему-то вываливается ошибка «file_get_contents(...): failed to open stream: Connection timed out in … on line ...». Пробовал увеличивать время выполнения скрипта и таймаут веб-сервера - не помогло. Так и не смог найти закономерность.
Тогда нашелся другой вариант - для загрузки ответа запроса использовать cURL . Чтобы применить такой метод, необходимо установить в ОС библиотеку libcurl, например, в Ubuntu - sudo apt-get install libcurl3
и включить в PHP поддержку cURL, например, в Ubuntu - sudo apt-get install php5-curl
Теперь можно открыть в PHP-скрипте сеанс curl функцией curl_init() , установить параметры соединения (в том числе URL) функцией curl_setopt() и скачивать контент JSON-файлов в строку функцией curl_exec() . Потом следует закрыть сеанс - curl_close() . Остальной код остается без изменений:
Весь код с cURL на PHP
// Номер пакета запроса
$packet = 0;
// Размер пакета запроса
$limit = 1000;
// Инициализируем cURL.
// Для работы с cURL должна быть установлена библиотека libcurl
// и включена поддержка cURL в PHP.
$ch = curl_init();
do {
// Каждый запрос начинаем там, где остановились в предыдущем запросе.
$offset = $ packet * $limit;
// Параметры запроса
curl_setopt($ch, CURLOPT_URL, "https://api.vk.com/method/groups.getMembers?group_id=habr&offset=$offset&fields=sex,bdate&version=5.27");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
// Выполнение запроса.
// Результат - JSON-файл с общим количеством и данными пользователей.
$content = curl_exec ($ch);
$members = json_decode($contents, true);
// Данные пользователей хранятся в подмассиве users.
// Каждый элемент users - ассоциированный массив с данными.
foreach ($members["response"]["users"] as $user_array) {
// Если пользователь указал дату рождения и пользователь - мужчина...
if ((isset($user_array["bdate"])) && ($user_array["sex"] == 2)) {
// ... и если в дате рождения три компонента (ДД.ММ.ГГГГ)...
if (count(explode(".", $user_array["bdate"])) == 3) {
// то вычисляем возраст (формулу нашел в интернете)
$age = floor((time()-strtotime($user_array["bdate"]))/(60*60*24*365.25));
// Если возраст нам подходит, выводим id пользователя с переводом строки
if ($age > 25) {
echo $user_array["uid"] . "
";
}
}
}
}
// Переходим на следующий пакет.
$packet++;
} while ($members["response"]["count"] > $offset + $limit);
// Закрываем cURL
curl_close ($ch);
Как я уже говорил, думаю, возможен подход с методом execute, но мне пока не удалось получить в этом направлении удовлетворительный результат.
P. S. Прошу не думать, что я хочу получить от аудитории «Хабра» решение тестового задания. Вышеприведенные варианты я уже давно отправил и получил ответ. Просто немало времени потратил на эту задачу и хотел бы узнать, в правильном направлении ли я двигался и какие еще подходы можно было бы использовать.
Довольно часто возникает необходимость указать id сообщества в вк. К примеру, когда мы , то в форме создания задания, нужно было указать ссылку (id) на нужную группу.
Сейчас я покажу вам, как это сделать. Мы разберем два возможных варианта.
Итак, как узнать id группы вконтакте .
Что такое id группы
Если вы помните, я уже показывал вам, . С группой все тоже самое. Нам нужен ее уникальный номер.
Тут возможно два варианта. Если администратор группы не редактировал уникальный URL, то при посещении сообщества, в адресной строке браузера, мы увидим интересующее нас значение. А вот если ссылка была изменена, здесь будет несколько сложнее.
Если id группы не изменялось
Здесь все просто. Открываем нужное сообщество, и смотрим в адресную строку. Значение после «com/» , будет искомое id.
В нашем примере искомое значение будет:
Club120208137
Как узнать id группы в вк, если ссылка была изменена
Здесь в разделе «Адрес страницы» , пишет то, что нам нужно. Нажимаем «Сохранить»
При этом, уникальный числовой номер для группы не изменится. Но теперь мы не увидим его в адресной строке браузера. Как теперь нам получить искомый id?
Тут нужно прибегнуть к одной хитрости. На главной странице группы нажмите на ссылку «Участники» .
В открывшемся окне нажмите на значок «Поиск» .
Мы перейдем к следующей странице. Здесь можно искать людей, среди участников сообщества. Но нас интересует не эта функция.
Посмотрите в адресную строку, что вы там видите? URL сайта Вконтакте, затем слово search , что означает поиск. И слово group , означающее — в группе. Проще говоря — искать в группе.
Видео урок: как узнать id группы вконтакте
Заключение
Ссылку с числовым id группы, можно увидеть при просмотре материалов, опубликованных в сообществе. Вы можете открыть фотографию, видео запись или пост на стене (см. ). Но не в каждой группе они есть, или доступны для просмотра. А вот список участников виден всегда. Поэтому мы и использовали его в этом примере.
Вопросы?
Вконтакте