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

Автоматическая рассылка сообщений WhatsApp (развитие)

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

Доброго времени суток всем!

На написание данной статьи меня вдохновила эта публикация.

К сожалению, в этой статье не было способа для отправки файлов в Whatsapp и я решил поправить это.

Итак, необходимо:

  • Python (у меня 3.10.10)

  • библиотеки к нему (полный список их чуть ниже)

  • зарегистрированный номер телефона в Whatsapp

  • Windows компьютер

  • ... ну и желание

Теперь обещанный requrements.txt

async-generator==1.10
attrs==23.1.0
certifi==2023.5.7
cffi==1.15.1
charset-normalizer==3.1.0
colorama==0.4.6
exceptiongroup==1.1.1
h11==0.14.0
idna==3.4
outcome==1.2.0
packaging==23.1
PyAutoIt==0.6.5
pycparser==2.21
PySocks==1.7.1
python-dotenv==1.0.0
requests==2.30.0
selenium==4.9.1
sniffio==1.3.0
sortedcontainers==2.4.0
tqdm==4.65.0
trio==0.22.0
trio-websocket==0.10.2
urllib3==2.0.2
webdriver-manager==3.8.6
wsproto==1.2.0

Установка вышеуказанных пакетов, за исключением PyAutoIt, производится через

pip install -r requrements.txt 

и проблем не вызовет.

Установка PyAutoit нужна потому, что Selenium, на момент написания статьи, не может послать текст и команды за пределы браузера. А нужно указать Windows Explorer что за файл подлежит отправке. К слову, AutoIt - прекрасный скриптованный язык для тех, кто хочет автоматизировать работу с приложениями, которые не имеют API. Он запросто может находить, вводить текст и нажимать на кнопочки в windows приложениях.

Поэтому устанавливаем его отдельно.

  1. Скачиваем дистрибутив отсюда

  2. Раскрываем архив, если тащили не через git clone

  3. Переходим в папку pyautoit-master

  4. И запускаем python setup.py install... впрочем в README.md этого пакета написано больше ;).

Ну вот, теперь мы готовы запустить файл whatsapp.py. Вот он

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import WebDriverWait
from time import sleep
import argparse
import autoit

options = webdriver.ChromeOptions()
# если у вас другой браузер, например FireFox, мы просто пишем options = webdriver.FirefoxOptions() .
# if you have the Mozilla Fifefox just write                   options = webdriver.FirefoxOptions()
options.add_argument('--allow-profiles-outside-user-dir')
options.add_argument('--enable-profile-shortcut-manager')
# УКАЖИТЕ ПУТЬ ГДЕ ЛЕЖИТ ВАШ python ФАЙЛ. Советую создать отдельную папку для него
# Specify the path to where your python file is located. I suggest you create a separate folder for it
options.add_argument(r'user-data-dir=x:\\yyyyyy\\zzzzzz\\') 
options.add_argument('--profile-directory=Profile 1')
options.add_argument('--profiling-flush=n')
options.add_argument('--enable-aggressive-domstorage-flushing')

# эти опции нужны чтобы подавить любые сообщения об ошибках  SSL, сертификатов и т.п. Но работает только последняя :(
# these options need to disabled any messages about bad ssl, certification & etc 
options.add_argument('--ignore-certificate-errors-spki-list')
options.add_argument('--ignore-certificate-errors')
options.add_argument('--ignore-ssl-errors')
options.add_argument('log-level=3')
# INFO = 0, 
# WARNING = 1, 
# LOG_ERROR = 2, 
# LOG_FATAL = 3.
# default is 0.

# Константы для Selenium
# Constants for Selenium
xpath = "//button[@data-testid='compose-btn-send']"
xpathAttach = "//div[@data-testid='conversation-clip']"
# xpathFile = "//button[@data-testid='attach-document']"
#xpathSendButton = "//div[@data-testid='send']" # data-testid = "send"
cssIdOfDocument = "[aria-label='Документ']"
cssIdOfSendButton = "[aria-label='Отправить']"

# Константы для AutoIt
# Constant for Autoit
idExplorerOpen = "[CLASS:#32770]"
idInputLine = "[CLASS:Edit; INSTANCE:1]"
idOpenButton = "Button1"

# номера телефонов для отправки
# numbers of  phones to send
numbers = ["+7xxxxxxxxxx", "+7xxxxxxxxxx", "+7xxxxxxxxxx"]

# текст по умолчанию
# default text
text = "Ничего нет"

# Мы запускаем браузер
# We are starting a browser
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# ждём его загрузки
# it takes some time to load it
wait = WebDriverWait(driver, 30)


def main(args):
    for number in numbers:
# создаём url страницы с телефонныи номером и текстом для отправки
# create a url page with a phone number and text to send
        url = f"https://web.whatsapp.com/send?phone={number}&text={args.text}"
# идём туда
# go to there
        driver.get(url)
# ждём загрузки страницы Whatsapp
# we are waiting for Whatsapp page to load
        wait.until(EC.element_to_be_clickable((By.XPATH, xpath)))

        if not (args.file is None) :
# нужно отправить файл
# ищем кнопку Attach
# need to send file
# now we look for the Attach Button and click on it
           driver.find_element(By.XPATH, xpathAttach).click()
# затем ищем кнопку "Документ" и щелкаем на ней. Используется атрибут CCS, потому что у него нет ID
# then  we look for the Document Button and click on it. Used CCS attribute because it doesn't have any ID
           driver.find_element(By.CSS_SELECTOR, cssIdOfDocument).click()

# подождать, когда активируется окно проводника Windows
# wait when the Windows's explorer window to activate
           autoit.win_wait_active(idExplorerOpen, 5)
# затем отправляем путь к файлу в строку ввода
# then we are sending the path of the file to input line
           autoit.control_send(idExplorerOpen, idInputLine, args.file)
# и нажимаем кнопку "Открыть" 
# and are clicking the Open Button 
           autoit.control_click(idExplorerOpen, idOpenButton)
# немного ждём загрузки файла
# it takes some time to load a file
           sleep(5)
# ищем кнопку "Отправить" и нажимаем на нее. Используется атрибут CCS, потому что у него нет ID
# we look for the Send Button and click on it. Used CCS attribute because it doesn't have any ID
           driver.find_element(By.CSS_SELECTOR, cssIdOfSendButton).click()
           
        else:
# теперь ищем кнопку "Отправить" и нажимаем на нее
# now we look for the Send Button and click on it
           driver.find_element(By.XPATH, xpath).click()
# требуется некоторое время для отправки файла или сообщения
# it takes some time to send a file or a message
        sleep(5)
# закрыть все
# close all
    driver.quit()


if __name__ == '__main__':
# мы разбираем параметры командной строки
# we are parsing command line parameters
     parser = argparse.ArgumentParser(description='Send information by Whatsapp')
     parser.add_argument('--text', help='Text for send', required=False, default = text)
     parser.add_argument('--file', help='File for send', required=False)
     args = parser.parse_args()
# начать отправку
# start sending
     main(args)

  

Я постарался документировать в комментариях практически все важные моменты этого приложения, причём на двух языках: на русском и на английском, если кто-то вдруг не владеет русским ;). Поэтому не буду отдельно расписывать его части, но если что-то не понятно, то пишите в комментарии. Постараюсь ответить.

Приложение запускается так

python whatsapp.py --text "Я посылаю тебе ... или тебя ;)" 

если нужно отправить текст

или так

python --text "Это очень важный файл" --file "x:\yyyyy\zzzzz\fileToSend.ext"

если нужно отправить файл с пояснением

Первый запуск приложения потребует скачивания драйверов, обязательно согласитесь с этим. Также нужно будет зарегистрировать whatsapp клиента на этом компьютере.

Дальше оно обычно запускается и оправляет всё без вопросов.

Соглашусь с автором поста, который меня вдохновил и процитирую его:

что данная статья не создана с целью научить вас спамить, флудить и портить жизнь людям иными способами. Этот материал несёт исключительно ознакомительный характер. Думайте, перед тем, как что-то делать.

Всем удачи!

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

Публикации

Истории

Работа

Data Scientist
61 вакансия
Python разработчик
138 вакансий

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