Search
Write a publication
Pull to refresh

Автопостинг сообщений в обсуждения Вконтакте

Предисловие


Многие любят фриланс и используют различные биржи для поиска заказов, а кто-то любит искать работу в группах ВК. Я отношу себя ко второй группе (хотя биржами тоже не брезгую). И так как в ВК довольно большая конкуренция и много сообщений постятся каждый день в обсуждениях, предназначенных для предложения услуг, нужно частенько размещать там свои предложения (я размещаю раз в день). Но таких групп большое количество и в один прекрасный момент мне надоело выкладывать свои сообщения ручками. Поэтому я решил сделать автопостинг, который бы это делал за меня. Можно также использовать нижеизложенное для постинга других объявлений.

Пишем код


Вконтакте предоставляет удобный API для работы с сервисом, но целесообразней будет воспользоваться библиотекой vk_api.

Также, я буду пользоваться библиотекой configparser и конфигом во избежание утечки моих данных.

Итак, библиотеки, которые понадобятся

main.py

import vk_api
from vk_api.utils import get_random_id
import json
import configparser
import time

Что из этого зачем нужно разберемся в ходе написания кода.

Так как мы будем постить сообщения через свой профиль, нам понадобится авторизоваться.
Для начала, создадим конфиг с данными (но можно и не создавать, просто указать в нужных строках свои данные).

Создаем config.ini, он выглядит следующим образом:

config.ini

[auth]
login = login
password = password

Обращаю ваше внимание, что после = строки в конфиге пишутся без кавычек.

Вытаскиваем данные из конфига:

main.py

config = configparser.ConfigParser()
config.read('config.ini')
login = config['auth']['login']
password = config['auth']['password']

А вот после того как мы вытащили эти строки, кавычки к ним добавятся автоматически.

Затем, нужно авторизоваться и получить доступ к API:

main.py

vk_session = vk_api.VkApi(login, password)
vk_session.auth()
vk = vk_session.get_api()

Последняя строка позволяет работать с методами апи как с классами, есть еще другой способ, но он неудобен:

vk_session.method("метод", "данные")

Отложим ненадолго написание кода и соберем данные групп в json. Если зайти в какое-либо обсуждение ВК, то мы увидим там что-то типа

topic-123123_456456

123123 — это ID сообщества, 456456 — ID обсуждения, соберем из них JSON, где сообщество будет ключом, а обсуждение — значением:

groups.json

{
"123123": "456456",
"234234": "567567"
}

Итак, собрали обсуждения, в которые будет происходить автопостинг, затем считаем наш JSON:

main.py

with open('groups.json') as file:
    loaded = json.load(file)

Далее, нужно разобраться, что мы будем постить. Создаем файл message.txt, в котором будет лежать наш пост и считываем его:

main.py

with open('message.txt', encoding='utf-8') as file:
    message = file.read()

encoding='utf-8' указываем в том случае, если текст написан на русском (сомневаюсь что в ВК кто-то будет писать на английском, но вдруг).

Далее, если нам нужно будет прикрепить картинку или что-то другое к нашему посту, добавим картинку:

main.py

photo = 'photo101010_321321'
# если нужно несколько - перечисляем через запятую внутри одних кавычек

Где 101010 — ID вашего профиля, 321321 — ID картинки, photo — тип контента. Апи принимает только в таком формате, так что тут без самодеятельности. Эта картинка нам понадобится попозже.

Далее, выложу весь последующий код и объясню по полочкам:

main.py


while True:  # бесконечный цикл, включающийся раз в сутки
    for group, topic in loaded.items():  # перебираем ID групп и обсуждений
        random = get_random_id()  # рандомное значение, должно быть уникальным для каждого запроса
        try:
            vk.board.createComment(group_id=group, topic_id=topic,
                                   message=message, attachments=photo, guid=random)  # метод для постинга, где group_id - ID группы, topic_id - ID обсуждения, message - ваше сообщение, attachments - то, что нужно прикрепить к посту, guid - ID запроса, должен быть уникальным
        except Exception as error:  # если возникнут ошибки то запишем их в файл для дальнейших разбирательств
            with open('errors.txt', 'a') as file:  # errors.txt нужно заранее создать
                file.write(group + '\n' + str(error) + '\n')  # будем писать на какой группе и какая ошибка произошла
        finally:
            time.sleep(10)  # очень важно делать перерывы между запросами
    time.sleep(86400)  # ждем сутки до следующего постинга

vk.board.createComment — метод для постинга сообщений в обсуждения. Помните мы писали vk = vk_session.get_api()? Вот как раз для такого удобного использования методов.

Делать except Exception неправильно, но тут это некритично, так что можно или оставить так, или потом в логе посмотреть какие будут ошибки и вписать их.

time.sleep(10) — нужно для того, чтобы не было запрета от ВК, с просьбой ввести капчу. Капчу можно обойти, но тогда ее нужно будет вводить через консоль, а нам то нужна автоматизация, поэтому лучше поставить побольше времени между запросами. У меня 10 секунд, но лучше ставить побольше, если много сообществ.

Ждать сутки можно и по-другому, через datetime например, для постинга в определенное время.

Код целиком:
import vk_api
from vk_api.utils import get_random_id
import json
import configparser
import time


config = configparser.ConfigParser()
config.read('config.ini')

login = config['auth']['login']
password = config['auth']['password']

vk_session = vk_api.VkApi(login, password)
vk_session.auth()
vk = vk_session.get_api()

with open('groups.json') as file:
    loaded = json.load(file)

with open('message.txt', encoding='utf-8') as file:
    message = file.read()

photo = 'photo101010_321321'

while True:
    for group, topic in loaded.items():
        random = get_random_id()
        try:
            vk.board.createComment(group_id=group, topic_id=topic,
                                   message=message, attachments=photo, guid=random)
        except Exception as error:
            with open('errors.txt', 'a') as file:
                file.write(group + '\n' + str(error) + '\n')
        finally:
            time.sleep(10)
    time.sleep(86400)


Послесловие


Статья написана для новичков, и для тех, кто хочет быстро сделать скрипт и не думать своей головой :)
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.