使用Selenium搭配chromedriver发送WhatsApp消息出现TimeoutException求助
无关日志报错说明
- 控制台出现的USB设备读取失败、蓝牙适配器初始化失败类报错,属于Chrome桌面端的系统层日志噪音,和Selenium脚本逻辑完全无关,不会影响脚本正常运行,可直接忽略。
超时异常的核心根因
你遇到的TimeoutException是脚本定位搜索框失败导致的,本质是两个问题叠加:
- 沿用了多年前旧教程的失效定位规则
旧代码中使用的//input[@title='Search or start new chat']定位逻辑,在当前版本WhatsApp Web中已经完全失效:- 当前搜索框不是
<input>标签,而是可编辑的<div>元素 - 元素的
title属性值会跟随系统语言变化,中文版系统下属性值是「搜索或开始新的聊天」,根本匹配不到旧代码里的英文关键词 - 代码中使用的
_2S1VP这类类名,是前端打包生成的动态哈希值,每次WhatsApp版本更新都会变化,不具备长期稳定性
- 当前搜索框不是
- 代码逻辑存在低级错误
你定义的contact是包含多个联系人名称的列表,但后续代码直接把整个列表传给send_keys()方法,没有做逐个遍历的处理,即便元素定位成功也会触发输入异常。
可落地的修正方案
第一步:启动Chrome时压制无关噪音日志
通过Chrome启动参数屏蔽USB、蓝牙类的系统日志,避免控制台信息混乱。
第二步:替换为稳定的元素定位规则
放弃依赖动态类名、固定title文本的定位逻辑,改用WhatsApp页面中相对固定的contenteditable、data-tab属性做匹配,适配当前版本的页面结构。
第三步:补全多联系人遍历逻辑
循环处理contact列表中的每一个联系人名称,依次完成搜索、点击、发送消息的流程。
第四步:替换硬编码等待逻辑
用显式等待替代固定的time.sleep(),匹配页面实际的加载速度,减少无效等待时间。
修正后可直接运行的测试代码
import time from selenium import webdriver from selenium.webdriver import Keys from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.chrome.options import Options from webdriver_manager.chrome import ChromeDriverManager # 配置常量 contact_list = ["cristobal de toro", "cristobal", "gonzalo molina"] send_text = "Hey, this message was sent using Selenium" # 配置Chrome启动参数,压制无关日志 chrome_options = Options() chrome_options.add_argument("--log-level=3") chrome_options.add_argument("--disable-usb-detection") chrome_options.add_argument("--disable-bluetooth") # 初始化驱动 driver = webdriver.Chrome( executable_path=ChromeDriverManager().install(), options=chrome_options ) driver.get("https://web.whatsapp.com") wait = WebDriverWait(driver, 50) # 等待扫码登录 print("Scan QR Code, And then Enter") input() print("Logged In") # 循环处理每个联系人 for target_contact in contact_list: # 定位搜索框(适配当前版本的稳定选择器) search_box = wait.until( EC.presence_of_element_located( (By.XPATH, "//div[@contenteditable='true' and @data-tab='3']") ) ) search_box.click() search_box.clear() search_box.send_keys(target_contact) time.sleep(2) # 定位搜索结果中匹配的联系人并点击 target = wait.until( EC.presence_of_element_located( (By.XPATH, f"//span[@title='{target_contact}']") ) ) target.click() time.sleep(2) # 定位消息输入框(适配当前版本的稳定选择器) msg_box = wait.until( EC.presence_of_element_located( (By.XPATH, "//div[@contenteditable='true' and @data-tab='10']") ) ) msg_box.send_keys(send_text + Keys.ENTER) time.sleep(3) driver.quit()
运行注意事项
- 扫码完成后不要立刻按回车,等WhatsApp Web主界面完全加载出侧边聊天列表后再按,避免页面未加载完成触发元素等待超时
- 如果后续WhatsApp Web更新后再次出现元素定位失败,优先检查
data-tab的属性值,这类值是WhatsApp页面结构中变化频率最低的标识,比动态类名稳定得多 - 不要在运行过程中手动切换、最小化WhatsApp的浏览器窗口,否则会触发页面的后台节流机制,导致元素加载变慢、等待超时
内容的提问来源于stack exchange,提问作者Cristobal Garcia
相关产品推荐
相关产品推荐

