def get_mutual( source_uid: tp.Optional[int] = None, target_uid: tp.Optional[int] = None, target_uids: tp.Optional[tp.List[int]] = None, order: str = "", count: tp.Optional[int] = None, offset: int = 0, progress=None, ) -> tp.Union[tp.List[int], tp.List[MutualFriends]]: """ Получить список идентификаторов общих друзей между парой пользователей. :param source_uid: Идентификатор пользователя, чьи друзья пересекаются с друзьями пользователя с идентификатором target_uid. :param target_uid: Идентификатор пользователя, с которым необходимо искать общих друзей. :param target_uids: Cписок идентификаторов пользователей, с которыми необходимо искать общих друзей. :param order: Порядок, в котором нужно вернуть список общих друзей. :param count: Количество общих друзей, которое нужно вернуть. :param offset: Смещение, необходимое для выборки определенного подмножества общих друзей. :param progress: Callback для отображения прогресса. """ if target_uids is None: params = { "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], "source_uid": source_uid if source_uid is not None else "", "target_uid": target_uid, "order": order, } response = session.get(f"friends.getMutual", params=params) response_json = response.json() if "error" in response_json or not response.ok: raise APIError(response_json["error"]["error_msg"]) return response_json["response"] responses = [] if progress is None: progress = lambda x: x for i in progress(range(math.ceil(len(target_uids) / 100))): params = { "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], "target_uids": ",".join(map(str, target_uids)), "order": order, "count": count if count is not None else "", "offset": offset + i * 100, } response = session.get(f"friends.getMutual", params=params) filee = response.json() if "error" in filee or not response.ok: raise APIError(filee["error"]["error_msg"]) for arg in filee["response"]: responses.append( MutualFriends( id=arg["id"], common_friends=arg["common_friends"], common_count=arg["common_count"], )) if i % 3 == 2: time.sleep(1) return responses
def get_mutual( source_uid: tp.Optional[int] = None, target_uid: tp.Optional[int] = None, target_uids: tp.Optional[tp.List[int]] = None, order: str = "", count: tp.Optional[int] = None, offset: int = 0, progress=tqdm, ) -> tp.Union[tp.List[int], tp.List[MutualFriends]]: """ Получить список идентификаторов общих друзей между парой пользователей. :param source_uid: Идентификатор пользователя, чьи друзья пересекаются с друзьями пользователя с идентификатором target_uid. :param target_uid: Идентификатор пользователя, с которым необходимо искать общих друзей. :param target_uids: Cписок идентификаторов пользователей, с которыми необходимо искать общих друзей. :param order: Порядок, в котором нужно вернуть список общих друзей. :param count: Количество общих друзей, которое нужно вернуть. :param offset: Смещение, необходимое для выборки определенного подмножества общих друзей. :param progress: Callback для отображения прогресса. """ if target_uids: x = [] y = int(len(target_uids) / 100) if int(len(target_uids) / 100) else 1 for t in progress(range(y)): offset = 100 * t r = session.get( f"friends.getMutual?access_token={config.VK_CONFIG['access_token']}" f"&source_uid={source_uid if source_uid else ''}" f"&target_uids={','.join(map(str, target_uids)) if target_uids else ''}&order={order if order else ''}" f"&count={count if count else ''}&offset={offset if offset else 0}" f"&v={config.VK_CONFIG['version']}").json() try: data = r["response"] except KeyError: raise APIError(r["error"]) x += [MutualFriends(**f) for f in data] # type: ignore if t % 3 == 2: time.sleep(1) return x else: r = session.get( f"friends.getMutual?access_token={config.VK_CONFIG['access_token']}" f"&source_uid={source_uid if source_uid else ''}&target_uid={target_uid if target_uid else ''}" f"&order={order if order else ''}" f"&count={count if count else ''}&offset={offset if offset else 0}" f"&v={config.VK_CONFIG['version']}").json() try: return r["response"] except KeyError: raise APIError(r["error"])
def get_friends( user_id: int, count: int = 5000, offset: int = 0, fields: tp.Optional[tp.List[str]] = None, ) -> FriendsResponse: """ Получить список идентификаторов друзей пользователя или расширенную информацию о друзьях пользователя (при использовании параметра fields). :param user_id: Идентификатор пользователя, список друзей для которого нужно получить. :param count: Количество друзей, которое нужно вернуть. :param offset: Смещение, необходимое для выборки определенного подмножества друзей. :param fields: Список полей, которые нужно получить для каждого пользователя. :return: Список идентификаторов друзей пользователя или список пользователей. """ user_data = { "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], "count": count, "user_id": user_id if user_id is not None else "", "fields": ",".join(fields) if fields is not None else "", "offset": offset, } response = session.get("friends.get", params=user_data) if "error" in response.json() or not response.ok: raise APIError(response.json()["error"]["error_msg"]) else: return FriendsResponse( count=response.json()["response"]["count"], items=response.json()["response"]["items"], )
def get_wall_execute( owner_id: str = "", domain: str = "", offset: int = 0, count: int = 10, max_count: int = 2500, filter: str = "owner", extended: int = 0, fields: tp.Optional[tp.List[str]] = None, progress=None, ) -> pandas.DataFrame: """ Возвращает список записей со стены пользователя или сообщества. @see: https://vk.com/dev/wall.get :param owner_id: Идентификатор пользователя или сообщества, со стены которого необходимо получить записи. :param domain: Короткий адрес пользователя или сообщества. :param offset: Смещение, необходимое для выборки определенного подмножества записей. :param count: Количество записей, которое необходимо получить (0 - все записи). :param max_count: Максимальное число записей, которое может быть получено за один запрос. :param filter: Определяет, какие типы записей на стене необходимо получить. :param extended: 1 — в ответе будут возвращены дополнительные поля profiles и groups, содержащие информацию о пользователях и сообществах. :param fields: Список дополнительных полей для профилей и сообществ, которые необходимо вернуть. :param progress: Callback для отображения прогресса. """ outdated = pandas.DataFrame() code = f""" return API.wall.get ({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": "0", "count": "1", "filter": "{filter}", "extended": "0", "fields": "" }}); """ data = {"code": code} response = session.post("execute", data=data).json() if "error" in response: raise APIError(response["error"]["error_msg"]) if not progress: progress = lambda x: x for _ in progress( range( 0, math.ceil( (response["response"]["count"] if count == 0 else count) / max_count))): outdated = outdated.append( pandas.json_normalize( get_posts_2500(owner_id, domain, offset, count, max_count, filter, extended, fields))) time.sleep(1) return outdated
def get_posts_2500( owner_id: str = "", domain: str = "", offset: int = 0, count: int = 10, max_count: int = 2500, filter: str = "owner", extended: int = 0, fields: tp.Optional[tp.List[str]] = None, ) -> tp.Dict[str, tp.Any]: # fmt: off script = f""" var i = 0; var result = []; while (i < {max_count}){{ if ({offset}+i+100 > {count}){{ result.push(API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": "{offset} +i", "count": "{count}-(i+{offset})", "filter": "{filter}", "extended": "{extended}", "fields": "{fields}" }})); }} result.push(API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": "{offset} +i", "count": "{count}", "filter": "{filter}", "extended": "{extended}", "fields": "{fields}" }})); i = i + {max_count}; }} return result; """ # fmt: on data = { "code": script, "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], } response = session.post("execute", data=data) doc = response.json() if "error" in doc or not response.ok: raise APIError(doc["error"]["error_msg"]) return doc["response"]["items"]
def get_posts_2500( owner_id: str = "", domain: str = "", offset: int = 0, count: int = 10, max_count: int = 2500, filter: str = "owner", extended: int = 0, fields: tp.Optional[tp.List[str]] = None, ) -> tp.Dict[str, tp.Any]: code = f"""var i = 0; var offset = {offset}; var response = []; while(i < 25) {{ i = i + 1; offset = offset + 100; response.push(API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": offset, "count": "{count}", "filter": "{filter}", "extended": "{extended}", "fields": "{fields}" }})); }} return response""" response = session.post( "execute", data={ "code": code, "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], }, ) doc = response.json() if not response.ok or "error" in doc: raise APIError(doc["error"]["error_msg"]) return doc["response"]["items"]
def get_wall_execute( owner_id: str = "", domain: str = "", offset: int = 0, count: int = 100, max_count: int = 2500, filter: str = "owner", extended: int = 0, fields: tp.Optional[tp.List[str]] = None, progress=tqdm, ) -> pd.DataFrame: """ Возвращает список записей со стены пользователя или сообщества. @see: https://vk.com/dev/wall.get :param owner_id: Идентификатор пользователя или сообщества, со стены которого необходимо получить записи. :param domain: Короткий адрес пользователя или сообщества. :param offset: Смещение, необходимое для выборки определенного подмножества записей. :param count: Количество записей, которое необходимо получить (0 - все записи). :param max_count: Максимальное число записей, которое может быть получено за один запрос. :param filter: Определяет, какие типы записей на стене необходимо получить. :param extended: 1 — в ответе будут возвращены дополнительные поля profiles и groups, содержащие информацию о пользователях и сообществах. :param fields: Список дополнительных полей для профилей и сообществ, которые необходимо вернуть. :param progress: Callback для отображения прогресса. """ params_: Params = { "owner_id": owner_id, "domain": domain, "offset": offset, "count": count, "filter": filter, "extended": extended, "fields": ",".join(fields) if fields else "", "max_count": max_count, } code = (""" var calls = 0, items = [], records = 0, params = """ + str(params_) + """, response = {"count":"1"}; if (params.count == 0){ params.count = 100; response = API.wall.get(params); records = response.count; items = items + response.items; calls = calls + 1; }else{ records = params.count; if (params.count >= 100){ params.count = 100; } } var max_calls = """ + str(max_count) + """ / 100; while(calls < max_calls && records > params.offset) { calls = calls + 1; response = API.wall.get(params); items = items + response.items; params.offset = params.offset + params.count; }; return { count: records, items: items };""") params = { "code": code, "access_token": config.VK_CONFIG["access_token"], "v": "5.126", "count": 0, } class Response(tp.TypedDict): items: list count: int res: Response = {"items": [], "count": 1} with progress(total=res["count"]) as pbar: while len(res["items"]) < res["count"]: j = session.post(url="execute", data=params).json() time.sleep(1) try: if j["response"]["items"]: res["items"] += j["response"]["items"] else: res["items"] += [ i for i in range(2500 if res["count"] - len(res["items"]) > 2500 else res["count"] - len(res["items"])) ] res["count"] = j["response"]["count"] except KeyError: raise APIError(j["error"]) params["count"] = int(res["count"]) pbar.total = res["count"] pbar.update(len(res["items"]) - params_["offset"]) params_["offset"] = len(res["items"]) return pd.DataFrame(res["items"])