Пишем отложенные сообщения для ВК на питоне
Данная проблема возникла у меня, когда мне нужно было уехать загород на несколько недель, при этом во время отъезда нужно было отправить сообщение в ВК, а доступа в интернет я не имел бы. Поискав информацию в интернете, я ничего не смог найти про отложенные сообщения в ВК, поэтому у меня остался только один вариант — придумать как реализовать свои отложенные сообщения для ВК.
Ну, в целом, задача была понятна и я её разбил на несколько этапов:
Как отслеживать время на компьютере
Каким образом переходить на странички нужных людей
Каким образом отправлять им сообщения
Самое просто было написать код для отслеживания времени на компьютере:
import time
dt = [int(i) for i in input("Введите дату отправки в формате mm:dd ").split(":")]
tm = [int(i) for i in input("Введите время отправки в формате hh:mm:ss: ").split(":")]
message = input("Введите сообщение: ")
while True:
if (tm[0] == time.localtime().tm_hour and tm[1] == time.localtime().tm_min and tm[2] == time.localtime().tm_sec
and dt[0] == time.localtime().tm_mon and dt[1] == time.localtime().tm_mday):
print(message)
print(time.localtime())
time.sleep(1)
Для того, чтобы переходить на странички нужных людей, я не придумал ничего лучше, чем задавать ссылки на них :/
Изучив странички в ВК, их можно разделить на два типа:
Которые находятся в списке друзей
Которые не находятся в списке друзей
Основное различие в них — разные кнопки для открытия окна сообщения:


Я решил использовать библиотеку selenium
На самом деле, всё решение свелось к тому, что нужно было начать со страницы входа в аккаунт и последовательно сохранять XPath’ы кнопок и полей ввода
Чтобы получить XPath элемента, мы на него наводимся мышкой, нажимаем правой кнопкой и выбираем «исследовать элемент», потом правой кнопкой на выделенный код и копируем XPath


Вход по QR-код невозможен в рамках нашей задачи, поэтому нажимаем «Войти другим способом»

Вводим номер телефона

Подтвердить другим способом

Пароль

Вводим пароль и нажимаем продолжить
После этого, мы попадаем на страницу новостей, теперь мы будем перебирать все ссылки, которые нам указали в начале и отправлять сообщения по-очереди

Когда перешли на страницу нажимаем на кнопку сообщения

В поле ввода вписываем наше сообщение и нажимаем «send»
По пути мы скопировали все пути для кнопок и полей ввода и теперь осталось написать код:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
dt = [int(i) for i in input("Введите дату отправки в формате mm:dd ").split(":")]
tm = [int(i) for i in input("Введите время отправки в формате hh:mm:ss: ").split(":")]
receivers = input("Вставьте ссылки получателей через запятую без пробелов: ").split(",")
message = input("Введите сообщение: ")
while True:
if (tm[0] == time.localtime().tm_hour and tm[1] == time.localtime().tm_min and tm[2] == time.localtime().tm_sec\
and dt[0] == time.localtime().tm_mon and dt[1] == time.localtime().tm_mday):
urls = ["https://vk.com/?to=c3RpbGxtb3J0YWw-",
"/html/body/div[14]/div/div/div/div[3]/div/div/div[2]/div[1]/div/div/section/div/div/div/div/div/div[2]/div/button[1]/span/span",
"/html/body/div[14]/div/div/div/div[3]/div/div/div[2]/div[1]/div/div/section/div/div/div/div/div/form/div[1]/div[3]/span/div/div[2]/input",
"/html/body/div[14]/div/div/div/div[3]/div/div/div[2]/div[1]/div/div/section/div/div/div/div/div/form/button[1]/span",
"/html/body/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div/form/div[3]/button/span/span",
"/html/body/div[1]/div/div/div/div/div[2]/div/div[2]/div/div/div/div/div[2]/div[1]/div/div/div[4]/div[2]/div[1]/span",
"/html/body/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div/form/div[1]/div[3]/div/div/input",
"/html/body/div[1]/div/div/div/div/div[1]/div[1]/div/div/div/div/form/div[2]/button[1]/span",
]
urls_send = ["//*[@id='mail_box_editable']",
"//*[@id='mail_box_send']/span/span"]
friend = "//*[@id='profile_redesigned']/div/div/div/div[2]/div[2]/div[2]/div/div[2]/div/div/div/div[1]/a/span/span"
not_friend = "#profile_redesigned > div > div > div > div.ProfileHeader.ProfileHeader--withSnowballs > div.ProfileHeader__in > div.ProfileHeader__wrapper > div > div.ProfileHeader__actions > div > div > div > div:nth-child(2) > a > span > span > svg"
# entrance
browser = webdriver.Chrome()
browser.maximize_window()
browser.get(urls[0])
time.sleep(5)
search = browser.find_element(By.XPATH, urls[1])
search.click()
time.sleep(5)
search = browser.find_element(By.XPATH, urls[2])
search.send_keys("login")
time.sleep(5)
search = browser.find_element(By.XPATH, urls[3])
search.click()
time.sleep(5)
search = browser.find_element(By.XPATH, urls[4])
search.click()
time.sleep(5)
search = browser.find_element(By.XPATH, urls[5])
search.click()
time.sleep(5)
search = browser.find_element(By.XPATH, urls[6])
search.send_keys("password")
time.sleep(5)
search = browser.find_element(By.XPATH, urls[7])
search.click()
time.sleep(5)
# sending
for receiver in receivers:
browser.get(receiver)
time.sleep(5)
try:
search = browser.find_element(By.CSS_SELECTOR, not_friend)
search.click()
except Exception:
search = browser.find_element(By.XPATH, friend)
search.click()
time.sleep(5)
search = browser.find_element(By.XPATH, urls_send[0])
search.send_keys(message)
time.sleep(5)
search = browser.find_element(By.XPATH, urls_send[1])
search.click()
print(time.localtime())
time.sleep(1)
Между каждым действием выставлена пауза в 5 секунд, чтобы страница успевала прогрузиться, иначе может возникнуть ошибка
Это, по сути, всё. Думаю, что это можно как-то оптимизировать, но для меня и так сошло
Во время отъезда проверил программу и она смогла отправить сообщение спустя 3 дня после запуска. Конечно же в конце дописал код, чтобы по завершению отправки сообщений компьютер сам выключился, просто решил его не вставлять сюда