@abdullokh_apo

Как лучше получить список участников сообщества в VK API?

Добрый вечер!
Возник вопрос с апи'шкой вк. Мне нужно получать список всех участников сообщества за максимально короткое время. Попробовал через стандартный groups.getMembers:
Пример кода

async def get_vk_users(group_name: str) -> list:
    url = f'https://api.vk.com/method/groups.getMembers?' \
                  f'access_token={vk_token}&' \
                  f'v={vk_version}&' \
                  f'group_id={group_name}&' \
                  f'fields={fields}&' \
                  f'offset={response}'
    async with aiohttp.ClientSession() as session:
        async with session.get(url=url) as req:
                result = (await req.json())['response']['items']
                return result


Проблема этого подхода - лимит. Максимум 3000 участников в секунду

Погуглив понял, что надо юзать execute.
Пример кода

async def get_all_users_lists(group_names: list):
    fields = ','.join(['sex', 'contacts', 'last_seen'])
    async with semaphore:
        users_lists = []

        for group_name in group_names:
            members_count = await _get_subscribers_quantity(group_name)
            group_users = []
            for offset_ in range(0, members_count, 25_000):
                code = f"""
var count = {members_count};
var offset = {offset_};
var i = 0;
var members = [];
while (i < 25 && offset < count){{
members = members + API.groups.getMembers({{"group_id":"prog_life", "count":1000, "offset": offset, "fields": {fields}}}).items;
    offset = offset + 1000;
    i = i + 1;
}}
return members;
"""
                async with aiohttp.ClientSession() as session:
                    data = {
                        "code": code,
                        "access_token": vk_token,
                        "v": vk_version,
                    }
                    async with session.post(url=f"https://api.vk.com/method/execute", data=data) as req:
                        response = await req.json()
                        print(response)
                        group_users.extend(response['response'])
                        await asyncio.sleep(0.35)
            users_lists.append(group_users)

        return users_lists



Ожидалось получить 25 000 пользователей в секунду. И действительно, это работает, но когда в code НЕ указывается аттрибут fields (то есть получаем пустые id'шки). Как только указал в fields хотя бы одно значение (contacts, например) время выполнения скрипта резко ухудшилось до ~10секунд/каждый запрос. Когда добавил еще одно значение (скажем, указал пол) ~30с/за 1 запрос.

И условно, если надо получить всех участников сообщества со 100К участниками, 4 запроса (по 25К) по 30 секунд = 2 минуты.

Не могу понять, это проблема в коде или в api? В любом из случаев, как это оптимизировать, в каком направлении копать?
  • Вопрос задан
  • 114 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы