Launch WhatsApp in a headless browser session

Use Case:

Automating the process of sending WhatsApp messages through pythonanywhere. Below is the step-by-step procedure:

  1. Non-programmers will record the phone numbers in a Google Sheet where messages need to be sent.
  2. The data from the Google Sheet is fetched (using gspread in pythonanywhere).
  3. Open WhatsApp’s online platform to distribute messages in bulk.

I already have a working script utilizing Selenium on my local machine that navigates to the WhatsApp web page, locates the required elements, and sends messages to the phone numbers listed in the Google Sheet. Here’s a relevant excerpt of my current script:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# Assuming other necessary code is in place

def initiate_driver():
    global driver
    driver = webdriver.Chrome()
    driver.get('https://web.whatsapp.com/')

    wait_count = 0
    while True:
        try:
            wait.until(EC.presence_of_element_located((By.XPATH, "//canvas[@aria-label='Scan me!']")))
            wait_count += 1
            if wait_count % 1000 == 0:
                print("Waiting for login confirmation...", 'WARNING')
        except:
            print("Successfully logged in to WhatsApp")
            break

for phone_entry in contacts:
    driver.find_element(By.XPATH, PHONE_INPUT_XPATH).send_keys(str(phone_entry['PhoneNumber']))
    time.sleep(2)
    driver.find_element(By.XPATH, PHONE_INPUT_XPATH).send_keys(Keys.ENTER)
    time.sleep(2)
    driver.find_element(By.CLASS_NAME, 'message_box_class').send_keys(str(phone_entry['Message']))
    time.sleep(2)
    driver.find_element(By.CLASS_NAME, 'send_button_class').click()
    time.sleep(2)

Question:

To complete the third step on pythonanywhere, using a headless browser is essential. However, initiating WhatsApp Web typically requires scanning a QR code, which poses a challenge. My current segment for headless Selenium is malfunctioning, producing an error: NoSuchElementException: Unable to locate element: {...}. I’m in a bit of a bind here. Any suggestions or ideas to work around this issue would be greatly appreciated, including recommendations for alternative libraries that might be suitable.

Thanks in advance!

Hey! Have you thought about using the selenium-wire package? It might help cuz it lets your manipulate HTTP requests and responses directly. Alternatively, trying the pyzbar library could be useful for decoding QR codes in headless modus if u can send it to another device’s cam. :wink:

I’ve encountered similar challenges using Selenium in a headless environment. A practical solution is to save cookies after the initial login session on a regular browser and then load these cookies in the headless session later on. This method bypasses the need for QR code scanning each time. When you log in once, save all session cookies, and then import these cookies at the start of your script in PythonAnywhere. This should help to maintain the authenticated session without visual confirmation.