Как стать автором
Обновить

Пишем отложенные сообщения для ВК на питоне

Уровень сложностиПростой
Время на прочтение4 мин
Количество просмотров1.4K

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

Ну, в целом, задача была понятна и я её разбил на несколько этапов:

  • Как отслеживать время на компьютере

  • Каким образом переходить на странички нужных людей

  • Каким образом отправлять им сообщения

Самое просто было написать код для отслеживания времени на компьютере:

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)

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

Изучив странички в ВК, их можно разделить на два типа:

  1. Которые находятся в списке друзей

  2. Которые не находятся в списке друзей

Основное различие в них - разные кнопки для открытия окна сообщения:

Не в списке друзей
Не в списке друзей
В списке друзей
В списке друзей

Я решил использовать библиотеку 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 дня после запуска. Конечно же в конце дописал код, чтобы по завершению отправки сообщений компьютер сам выключился, просто решил его не вставлять сюда

Теги:
Хабы:
Всего голосов 4: ↑3 и ↓1+2
Комментарии3

Публикации

Работа

Data Scientist
55 вакансий

Ближайшие события