Доброго времени суток всем!
На написание данной статьи меня вдохновила эта публикация.
К сожалению, в этой статье не было способа для отправки файлов в 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 приложениях.
Поэтому устанавливаем его отдельно.
Скачиваем дистрибутив отсюда
Раскрываем архив, если тащили не через git clone
Переходим в папку pyautoit-master
И запускаем 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 клиента на этом компьютере.
Дальше оно обычно запускается и оправляет всё без вопросов.
Соглашусь с автором поста, который меня вдохновил и процитирую его:
что данная статья не создана с целью научить вас спамить, флудить и портить жизнь людям иными способами. Этот материал несёт исключительно ознакомительный характер. Думайте, перед тем, как что-то делать.
Всем удачи!
