How to launch WhatsApp Web in headless Chrome browser

My situation:

I’m trying to build an automated WhatsApp messaging system that runs on a remote server. Here’s what I want to do:

  1. Read contact numbers from a Google spreadsheet
  2. Process this data using Python scripts
  3. Launch WhatsApp Web automatically to send bulk messages

I have working code that runs fine on my local computer with a visible browser:

browser = webdriver.Chrome()
browser.get('https://web.whatsapp.com/')
wait_element = WebDriverWait(browser, 30)
login_attempts = 0
while True:
    try:
        wait_element.until(EC.presence_of_element_located((By.XPATH, "//canvas[@aria-label='Scan me!']")))
        login_attempts += 1
        if login_attempts % 500 == 0:
            print("Still waiting for QR scan...")
    except:
        print("Successfully logged into WhatsApp")
        break

for contact in contact_list:
    browser.find_element_by_xpath(CONTACT_INPUT_FIELD).send_keys(str(contact['Number']))
    time.sleep(1)
    browser.find_element_by_xpath(CONTACT_INPUT_FIELD).send_keys(Keys.ENTER)
    time.sleep(1)
    browser.find_element_by_class_name('message_input').send_keys(str(contact['Text']))
    time.sleep(1)
    browser.find_element_by_class_name('send_button').click()
    time.sleep(1)

The problem:

When I try to run this headless, I can’t complete the QR code authentication step. My headless setup fails with element not found errors:

options = webdriver.ChromeOptions()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
browser = webdriver.Chrome(options=options)

def automate_whatsapp():
    browser.get('https://web.whatsapp.com/')
    
    for contact in contact_list:
        browser.find_element_by_xpath("//div[@contenteditable='true']").send_keys(str(contact['Number']))
        time.sleep(1)
        browser.find_element_by_xpath("//div[@contenteditable='true']").send_keys(Keys.ENTER)
        time.sleep(1)
        browser.find_element_by_class_name('message_input').send_keys(str(contact['Text']))
        time.sleep(1)
        browser.find_element_by_class_name('send_button').click()
        time.sleep(1)
        print(f"Message sent to {contact['Number']} - {contact['Name']}")

Is there any way to handle WhatsApp Web authentication in headless mode? I’m open to using different Python libraries if needed.

The problem is WhatsApp Web needs QR code scanning to authenticate, which doesn’t work in headless mode. But there’s a workaround I’ve used in production. Save your browser session after the first login. Run your script once in regular mode (not headless) and add --user-data-dir=/path/to/profile to your Chrome options. Do the QR scan like normal, then close the browser. Now you can run headless mode using that same user data directory - WhatsApp Web will load without needing another QR scan. Just handle session expiration if you don’t use it for a while. Fair warning though - WhatsApp actively blocks bots now. You’ll likely hit rate limits or account restrictions with bulk messages. Add random delays and keep message frequency low to avoid getting flagged.

the qr thing is unavoidable in headless mode, but here’s a workaround: use selenium-wire to save your session data after logging in the first time. then inject those cookies/tokens when you run headless. works most of the time, though whatsapp keeps updating their security so it breaks occasionally. just a heads up - they’re cracking down hard on automation lately. don’t go overboard with bulk messaging or you’ll get banned fast.

Had this exact problem when automating WhatsApp for client notifications. Headless browsers can’t show the QR code properly - that’s your main issue. Here’s what worked for me: start with a regular browser window, do the QR scan, then switch to headless mode. You can use browser.execute_script() to change window properties or restart with saved cookies/localStorage. On Linux servers, try Xvfb - gives you a virtual display so you can scan QR codes while staying “headless.” Just be super careful with bulk messaging. WhatsApp’s detection is pretty good and they’ll ban you permanently if you’re not careful. For legit business stuff, their Business API is probably your better bet.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.