avk ⚛️ формирование Atom-ленты для пабликов ВКонтакте
Ещё с конца 2024 года (и, как минимум, первую половину января 2025-го) RSS-bridge стал просто отвратительно работать с ВКонтакте. Видимо всё началось после какого-то обновления со стороны ВК. Сервер https://rss-bridge.org/bridge01/ просто отказался работать. Через какое-то время, спасибо sn4il'у, на сервере https://rss.thedroth.rocks/ стал работать второй мост (VK2). Но и он работал как-то не идеально: чем дальше, тем чаще стал возвращать ошибку (Bridge returned error 500!).
Я, например, не пользуюсь рекомендательными алгоритмами музыкальных платформ и предпочитаю следить напрямую за интересующими меня музыкантами. А некоторые русскоязычные артисты ведут только свой ВК. Но, конечно, зарегистрироваться и сидеть из-за этого в ВК я не намерен.
Поэтому я решил написать свой скапер содержимого пабликов ВКонтакте. Я заметил, что мобильная версия сайта (https://m.vk.com/<xxx>) отдаёт содержимое последних пяти записей. Точнее закреплённую запись (или их может быть несколько?) и четырёх наиболее свежих (или менее). После беглого просмотра дампа работы браузера, я понял что ВК отдаёт содержимое записей при заполненности некоторых кук (cookies). Основную массу значений он отдаёт сам в ответе, но нужно ещё добавить куку с именем "remixmdevice" и значением, например, "1920/1080/1/!". То есть нехитрыми шагами (запрос, добавление куки, второй запрос) мы получаем заглавную станицу ВК-паблика с содержимым пяти записей.
Далее дело за малым: разбираем HTML, следим за тэгами и их классами, запоминаем текущий стек классов элементов <div> и (на основе всего этого) формируем Atom-ленту. Я понимаю, что имена классов это не самое надёжное средство ориентирования в содержимом страницы, но мне кажется, что в будущем мне проще будет перебить новые константы после обновления интерфейса со стороны ВК, чем тащить ради этой задачи какой-нибудь Beautiful Soup, который всё равно не будет универсальным средством.
Простоя реализация avk.py позволила не использовать внешних зависимостей. Для решения задачи хватило стандартной библиотеки Python:
- urllib.request для выполнения запроса к m.vk.com
- html.parser для разбора ответа от m.vk.com
- http.server для HTTP сервера, который и отдаёт Atom-ленту
Получившийся HTTP сервер (https://avk.any-key.press/) ожидает имя ВК-паблика в параметре name. Например, что бы получить Atom-ленту для страницы https://vk.com/security нужно выполнить запрос https://avk.any-key.press/?name=security
Если кому-то будет полезно - добро пожаловать, пользуйтесь.
Но стоит учитывать, что сервер не хранит состояние. То есть в формируемой ленте всегда будет пять записей (включая закреплённые). Поэтому, если это возможно, стоит настроить частоту обновления в вашем RSS-агрегаторе так, что бы не терять данные. Если между двумя запросами Atom-ленты в ВК-паблике будет опубликовано более пяти сообщений, то часть публикаций будет утеряна.
Исходный код можно найти в git-репозитории:
Web интерфейс к git репозиторию
Вопросы, предложения и тому подобное вы можете:
- слать по электронной почте: avk@to.any-key.press
- оформить ответом к моему посту в ActivityPub: