vk-parser-1.md 26.07.2026

Парсер публикаций ВКонтакте

Парсер для VK: находит подходящие посты в поиске новостей и ставит их в предложку своих групп, с защитой от повторов.

Задача

Автоматически наполнять ленту предложки сообществ релевантными постами из других пабликов. На входе — список сообществ с поисковым запросом, словами-исключениями и периодом, на выходе — запланированные публикации. Токен один, с правами админа только своих групп.

Как делал

Главная сложность — newsfeed.search отдаёт не больше ~200 результатов на запрос. Период режется на шестичасовые окна, и внутри каждого окна идёт пагинация через offset со сдвигом по 100. Так поиск обходится всей лентой за сутки, а не первыми двумястами.

Слова-исключения не фильтруются в коде, а уходят прямо в запрос как -слово. Отсев происходит на стороне поиска, до выборки, и лишние посты просто не приходят.

Дедупликация трёхуровневая. Первый уровень — пара owner_id_id: между страницами пагинации VK отдаёт пересечения. Второй — хеш содержимого внутри запуска: один и тот же текст от разных авторов. Третий — seen_hashes.json, история между запусками.

Хеш считается не от ID, а от текста с нормализованными пробелами плюс набор типов вложений с количеством, отсортированный. ID вложений в хеш не входят намеренно: при перепечатке они всегда новые, и хеш по ID ломался бы на каждом репосте.

Файл с хешами пишется атомарно — сначала .tmp, потом os.replace(). Плюс сохранение после каждого отправленного поста и регистрация через atexit. Прерывание посреди публикации не даёт ни битого JSON, ни повторного прогона уже ушедших постов.

Публикация в предложку планируется с запасом вперёд, и на каждый сдвиг есть три попытки: VK возвращает ошибку, если две публикации попали на одну минуту.

Ретраи в vk_request разделены по типу сбоя: rate limit с кодом 6 ждёт пять секунд, HTML вместо JSON или Too Large — десять, таймаут — три, обрыв соединения — линейно с ростом попытки. Невалидный ответ уходит в errors.log с превью первых трёхсот символов, потому что текст ошибки VK сам по себе бесполезен.

Отдельно проверяются лимиты VK: 10 000 символов на пост, 10 вложений и 4 096 символов для личных сообщений — у ЛС лимит ниже, поэтому текст режется с записью в лог. Сборка в один .exe делается PyInstaller под Wine, и путь к конфигу ищется и рядом с бинарником, и в рабочей папке — у sys.frozen домашний каталог всегда один.

Итог

Один файл на 480 строк, requests без обёрток, конфиг в JSONC с комментариями. test_mode переключает отправку из предложки в личку — отладка не засоряет ленту. Windows-сборка запускается без установленного Python.

// похожие проекты

Ещё работы

// проект 2026
Скриншот страницы сайта chetaika с попапом

Chetaika. Книжный поисковик

Книжный поисковик поверх Google Books API: один HTML-файл, два serverless-прокси и чистый vanilla JS без зависимостей.

// проект 2026
Скриншот страницы сайта YTWrapped

YT-wrapped. Аналитика YouTube-каналов

Аналитика YouTube-каналов: поиск, разбор последних 50 видео, вовлечённость, частота загрузок и рейтинг роликов.

// проект 2026
Скриншот главной страницы лединга AROMA

Aroma. Лендинг кофейни

Одностраничный лендинг кофейни: атмосфера, меню с фильтрами и каруселью, форма бронирования с модалкой подтверждения.

// проект 2026
Нет изображения

Парсер цены товара Ozon по ID

Скрипт по ID товара Ozon читает цену покупателя из зелёной плашки, отдаёт её в JSON и сам переживает антибот-проверку Ozon.

// проект 2026
Скриншот главной страницы лендинга ИГРАЙ-КА

«Играй-ка». Лендинг магазина игрушек

Одностраничный лендинг магазина детских игрушек: витрина, категории, отзывы и форма заявки.

// проект 2026
Нет изображения

Бот для сбора лидов из Telegram-каналов и RSS

Бот для Telegram: читает каналы и RSS-ленты, фильтрует заказы по ключевым словам с весами и присылает подходящие в личку.

> все проекты

// contact.php

Ну что, работаем?

Опишите задачу — разберусь и предложу решение.