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"])
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, ) -> 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 для отображения прогресса. """ response = session.post( url="execute", data={ "code": f""" return API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": {offset}, "count": "1", "filter": "{filter}", "extended": {extended}, "v": {config.VK_CONFIG["version"]} }}); """, "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], }, ).json() if "error" in response: raise APIError posts = response["response"] if response["response"]["count"] - offset > count and count != 0: max_count = count else: max_count = response["response"]["count"] - offset if max_count == 0: return json_normalize(posts["items"]) window = range(0, max_count, 100) if progress: window = progress(window) num_records = max_count - len(posts) for i in window: try: posts2500 = get_posts_2500( owner_id=owner_id, domain=domain, offset=offset + len(posts), max_count=num_records, filter=filter, extended=extended, fields=fields, ) posts.update(posts2500) if not (max_count - len(posts)) > num_records: num_records = max_count - len(posts) except: raise APIError time.sleep(0.34) return json_normalize(posts["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]: if fields: code_fields = "?".join(fields) else: code_fields = "" if max_count <= 100: code = f""" return API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": {offset}, "count": {max_count}, "filter": "{filter}", "extended": {extended}, "fields": "{code_fields}", "v": {config.VK_CONFIG["version"]} }}).items; """ else: if max_count > 2500: max_count = 2500 code = f""" var wall_records = []; var offset = 100 + {offset}; var count = {count}; var max_offset = offset + {max_count}; while (offset < max_offset && wall_records.length <= offset && offset-{offset} < {max_count}) {{ if ({max_count} - wall_records.length < 100) {{ count = {max_count} - wall_records.length; }}; wall_records = wall_records + API.wall.get({{ "owner_id": "{owner_id}", "domain": "{domain}", "offset": offset, "count": count, "filter": "{filter}", "extended": {extended}, "fields": "{code_fields}", "v": {config.VK_CONFIG["version"]} }}).items; offset = offset + 100; }}; return wall_records; """ response = session.post( url="execute", data={ "code": code, "access_token": config.VK_CONFIG["access_token"], "v": config.VK_CONFIG["version"], }, ).json() if "response" in response: return response["response"] raise APIError