Недавно мне понадобилось получить отсортированный по лайкам или репостам список записей со страницы в VK. Готового решения я не нашел, пришлось решать задачу самостоятельно. В итоге получилось простенькое приложение, работающее достаточно быстро.
Требования к приложению заключались в следующем. На вход подается ссылка на страницу и дополнительные параметры. Сперва был только один параметр — ключ сортировки, позже был добавлен параметр, задающий промежуток времени (в днях). Посты, опубликованные раньше этого промежутка, не учитываются. Например, при значении параметра 7 на выходе получим список постов с максимальным количеством лайков (или репостов) за поледнюю неделю.
Для решения задачи использовал Python 3 и модуль Requests. Некоторые детали реализации не описываются, полный код доступен по ссылке, в конце статьи. Итак, приступим.
Для начала нужно распарсить аргументы командной строки. Для этого воспользуемся модулем argparse из стандартной библиотеки:
parse_args
Как сделать пост в группе ВК, который точно «зайдет»?
def parse_args(): «»» Parses input arguments «»» parser = argparse.ArgumentParser() parser.add_argument(‘url’, action=’store’, default=None, help=’target page’, type=url_validator) compar_key = parser.add_mutually_exclusive_group() compar_key.add_argument(‘-l’, ‘—likes’, help=’sort posts by likes’, action=’store_true’, default=True) compar_key.add_argument(‘-r’, ‘—reposts’, help=’sort posts by reposts’, action=’store_true’) parser.add_argument(‘-t’, ‘—top’, help=’number of showing posts.’, default=10, type=num_validator) parser.add_argument(‘-d’, ‘—days’, type=int, default=-1, help=’period for post processing.’) return parser.parse_args()
Для проверки введенного url используется функция url_validator, которая, в случае успеха, возвращает словарь, содержащий тип введенного url и идентификатора страницы:
url_validator
def url_validator(arg): «»» Checks correctness of url argument «»» arg = arg.lower() # If url something like https://vk.com/textual_id matched_txt_id = const.TXT_ID_REGEXP.match(arg) if matched_txt_id: url = matched_txt_id.groupdict() url[‘type’] = ‘symbolic’ return url # If url something like https://vk.com/id123456 matched_numeric_id = const.NUM_ID_REGEXP.match(arg) if matched_numeric_id: return matched_numeric_id.groupdict() raise argparse.ArgumentTypeError( const.INVALID_URL.format(url=arg))
>> url_validator(«club123456»)
>> url_validator(«https://vk.com/habr»)
Результат парсинга входных данных, например, для
python vktop.py vk.com/habr -t 10 -l -d 10
Выглядит следующим образом:
>> args = parse_args() Namespace(days=10, likes=True, reposts=False, top=10, url=)
Для дальнейшей работы с API и формирования ссылок на записи, требуется числовой ID страницы:
get_page_id
def get_page_id(url): «»» Returns page’s numeric ID «»» if url[‘type’] not in [‘id’, ‘public’, ‘event’, ‘club’]: params = request = requests.get(const.API_URL + ‘utils.resolveScreenName?’, params=params) response = json.loads(request.text)[‘response’] if response: if response[‘type’] == ‘user’: return response[‘object_id’] else: # Groups have negative id return -response[‘object_id’] else: raise PageNotAvailable(url[‘id’] + ‘ is not available’) if url[‘type’] == ‘id’: return int(url[‘id’]) else: return -int(url[‘id’])
Теперь перейдем непосредственно к работе с VK API.
Как найти и посмотреть первую записьпостновостьсообщение в группе Вконтакте VK (2020)
Основной метод для получения записей — wall.get, за один запрос может вернуть максимум 100 постов, что достаточно мало. Для решения проблемы воспользуемся методом execute — универсальным методом, который позволяет запускать последовательность других методов, сохраняя и фильтруя промежуточные результаты. За один запрос execute может выполнить не более 25 обращений к API, из чего следует, что за один запрос к execute мы будем получать не 100 записей, как при обычном wall.get, а 2500. Execute имеет обязательный параметр code — код алгоритма в VKScript, формате, похожем на JavaSсript.
Запросы к API выполняются в цикле:
recieve_posts
def recieve_posts(page_id): «»» Returns :received_posts: from :page_id: «»» params = received_posts = [] offset = 0 while True: params[‘offset’] = offset response = json.loads(requests.post( const.API_URL + ‘execute.getPosts?’, params=params).text) # Interrupt loop when all posts were received if not response[‘response’]: break received_data = response[‘response’] for chunk in received_data: for post in chunk: received_posts.append(post) offset += 1 return received_posts
В примере используется метод execute.getPosts — хранимая процедура, которая создана для удобства в настройках приложения в VK, что позволяет не передавать каждый раз код метода, а обращаться к нему по имени.
Тело execute.getPosts
// количество итераций циклазапросов к API var ITERS = 25; // количество сообщений получаемых за один запрос var COUNT = 100; // список полученных постов var posts = []; var req_params = < «owner_id» : Args.id, // id страницы «offset» : 0, // смещение «count» : COUNT, «v» : «5.34» // версия API >; var i = 0; while(i < ITERS) < req_params.offset = i*COUNT + ITERS*COUNT*Args.offset; // Делаем запрос к API var items = API.wall.get(req_params).items; // Пустой список означает, что все записи получены if (items.length == 0) < return posts; >// Добавляем промежуточный результат // в итоговый список posts.push(items); i = i + 1; > return posts;
Код, приведенный выше, неэффективен, т.к. получает много лишней информации о записях, что существенно увеличивает время получения и дальнейшей обработки. Например, при получении 30.000+ постов с одной страницы, суммарный объем полученного текста может составлять более 50 Мб.
Проведем фильтрацию ответов на стороне сервера, что значительно ускорит работу приложения:
Измененный execute.getPosts
response: [< ids: [677448, 649369, 593585], dates: [1450981583, 1449937068, 1448431475], likes: [14957, 14923, 15493] >, < ids: [555311, 549734, 549376], dates: [1447699602, 1447677107, 1447675941], likes: [12384, 122548, 26709] >]
Как видим, количество получаемой информации сократилось в разы. Казалось бы, такой результат должен удовлетворить, но, как упоминалось в начале статьи, есть параметр, задающий промежуток времени (в днях). Код выше никак не учитывает его.
Например, если требуется получить самые популярные посты за последние два дня, то сначала скачиваются все посты, после чего локально отбираются те, которые опубликованы не ранее 2-ух прошлый дней. Таким образом, потенциальных постов, удовлетворяющих запросу, может быть штук 10, а получено будет несколько тысяч, что неприемлемо.
Передадим дополнительный параметр в метод execute.getPosts — крайнюю допустимую дату публикации в формате Unix Timestamp. Затем сравним последний полученный пост с этой датой. Если пост опубликован раньше, то возвращаем текущий список записей.
Итоговый метод execute.getPosts
Код execute.getPosts получился достаточно неуклюжим. Это связано с ограничением на количество операций за один запрос.
Итоговая функция для получения постов:
recieve_posts
def recieve_posts(page_id, last_days, reposts): «»» Returns posts from :page_id: that were posted not earlier than :last_days: ago «»» deadline = datetime.now() — timedelta(days=last_days) unix_stamp = int(deadline.strftime(«%s»)) if reposts: compar_key = const.REPOSTS else: compar_key = const.LIKES params = received_posts = [] offset = 0 ONGOING = True while ONGOING: params[‘offset’] = offset response = json.loads(requests.post( const.API_URL + ‘execute.getPostsNew?’, params=params).text) # Interrupt loop when all posts were received if not response[‘response’]: break received_data = response[‘response’] for chunk in received_data: chunk_size = len(chunk[‘ids’]) for i in range(chunk_size): post = dict() post[‘date’] = datetime.fromtimestamp(chunk[‘dates’][i]) if last_days == -1 or post[‘date’].year >= deadline.year and post[‘date’].month >= deadline.month and post[‘date’].day >= deadline.day: post[‘id’] = chunk[‘ids’][i] post[compar_key] = chunk[compar_key][i] received_posts.append(post) if ‘stop’ in chunk: ONGOING = False break offset += 1 return received_posts
Теперь, когда у нас есть нужные посты, остается только отсортировать и вывести их на экран.
Пример работы. Получаем самые популярные посты в сообществе хабра за последний месяц:
Полный код доступен на Github.
Источник: habr.com
Поиск записей с большим количеством лайков Вконтакте
Прокручивая новостную ленту Вконтакте, не всегда встретишь по-настоящему интересные и остроумные посты, на которых хочется остановиться. Сервис социальной сети Вконтакте дает нам возможность сделать выборку новостей, которые собрали сотни, тысячи, а некоторые и миллионы «лайков» и «репостов».
В этой статье мы расскажем, как без труда просматривать только те новости, которые оценили большинство пользователей Вконтакте.
Учимся находить самое интересное
Открываем свою личную страницу, находим слева основное меню. Открываем вкладку «Новости». В открывшемся окне кликаем кнопку «Поиск». Она расположена справа:
Сверху в поисковой строке нужно вбить по-английски «Лайки», затем поставить двоеточие, и написать число, эквивалентное количеству собранных постом лайков. Это число будет минимальным. Допустим, мы хотим посмотреть те новости, которые за последнее время набрали больше 100 лайков. Запись в поисковой строке будет выглядеть как «likes:100»:
После выполнения этого действия, система отсортирует и выведет вам список только тех записей, которые набрали за последние несколько минут больше 100 лайков. Таким же образом можно посмотреть новости, которые собрали более 1000 лайков. Запись в поисковой строке тогда будет выглядеть так: « likes:1000»:
Такими не сложными действиями можно увидеть, какие из постов стали самыми популярными за последнее время.
Активируем функцию «Самые интересные» посты
Если вы хотите, чтобы система отбирала для вас новости, которые за всё время набрали наибольшее количество лайков и репостов, нужно всего лишь активировать такой запрос. Там же, справа в меню находим «горящий» значок «Сначала интересные» и мышкой передвигаем бегунок вправо. Готово!
Теперь в первых рядах вашей новостной ленты вы будете видеть самые интересные и полезные записи, собравшие больше всего симпатий Вконтакте.
Источник: vksos.com
Как находить самые популярные посты конкурентов «ВКонтакте»
Долго я искал решение, чтобы сортировать посты «ВКонтакте» по разным критериям: лайки, репосты, комментарии. Но все, что находил, было платным или ограничивало функционал. Недавно нашел бесплатный сервис для поиска вирусного контента и хочу им поделиться.
Таким инструментом оказалось небольшое приложение Посты ВКонтакте. Приложение бесплатное, быстрое, удобное и продуманное.
Распишу подробную инструкцию работы с сервисом.
1. Выберите источники для отслеживания
Можно настроить аналитику на свое сообщество и находить вечнозеленый контент или искать классные посты конкурентов.
2. Сортируем и выбираем нужный период
Результаты поиска можно отсортировать. Убывание лайков на 1 просмотр ставьте, когда в списке для анализа много пабликов с большим разбросом подписчиков, чтобы не потерять интересные посты от небольших сообществ.
В Spark я использую этот сервис для поиска вечнозеленого контента. Возможно, и у вас есть старые посты, которыми стоит еще раз поделиться с подписчиками.
Источник: spark.ru