You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pywhatkit.sendwhatmsg无法发送消息,Tkinter GUI问题排查

问题分析与解决方案:AldiChat无法批量发送WhatsApp消息

问题概述

我开发了一款基于Tkinter的AldiChat GUI程序,用于通过pywhatkit批量发送WhatsApp消息。程序可正常读取CSV文件中的手机号并展示,但点击发送按钮后无法成功发送消息,控制台无任何报错。单独测试pywhatkit.sendwhatmsg的示例代码可正常运行,怀疑问题出在GUI相关逻辑或send_whatsapp_message函数中。

核心发送函数代码:

def send_whatsapp_message():
    selected_numbers = numbers_listbox.curselection()
    message = message_entry.get()
    
    for index in selected_numbers:
        number = numbers_listbox.get(index)
        kit.sendwhatmsg(f'+{number}', message, 0, 0)  # 立即发送

我通过f-string为手机号添加+号(格式从39XXXXXXXXXX转为+39XXXXXXXXXX),尝试直接指定号码也无法生效。请问是否是GUI导致的问题?

完整代码如下:

import tkinter as tk
from tkinter import filedialog
import pywhatkit as kit
import csv

def open_csv_file():
    file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
    if file_path:
        with open(file_path, 'r') as file:
            reader = csv.reader(file)
            for row in reader:
                numbers_listbox.insert(tk.END, row[0])  # 假设手机号在第一列

def send_whatsapp_message():
    selected_numbers = numbers_listbox.curselection()
    message = message_entry.get()
    
    for index in selected_numbers:
        number = numbers_listbox.get(index)
        kit.sendwhatmsg(f'+{number}', message, 0, 0)  # 立即发送
    
    
    # 清空消息输入框
    message_entry.delete(0, tk.END)

def browse_file():
    file_path = filedialog.askopenfilename()
    if file_path:
        attached_file_label.config(text=file_path)

# 创建主窗口
root = tk.Tk()
root.title("AldiChat")

# 消息标签和输入框
message_label = tk.Label(root, text="输入消息:")
message_label.pack()
message_entry = tk.Entry(root, width=40)
message_entry.pack()

# 打开CSV文件按钮
open_csv_button = tk.Button(root, text="打开联系人文件", command=open_csv_file)
open_csv_button.pack()

# CSV中的手机号列表框
numbers_listbox = tk.Listbox(root, selectmode=tk.MULTIPLE)
numbers_listbox.pack()

# 立即发送WhatsApp消息按钮
send_button = tk.Button(root, text="立即发送WhatsApp消息", command=send_whatsapp_message)
send_button.pack()

# 附加文件按钮
attach_file_button = tk.Button(root, text="附加文件", command=browse_file)
attach_file_button.pack()

# 显示附加文件路径的标签
attached_file_label = tk.Label(root, text="")
attached_file_label.pack()

# 启动GUI
root.mainloop()

问题原因分析

  1. Tkinter主线程阻塞:pywhatkit.sendwhatmsg会启动浏览器并执行一系列操作,这个过程会占用主线程,导致Tkinter GUI冻结,同时可能因为主线程被阻塞,导致pywhatkit的操作无法正常完成。
  2. 时间参数错误:sendwhatmsg传入的0,0会被解析为午夜12点,并非“立即发送”。pywhatkit的立即发送需要使用专门的方法,或计算当前时间加1分钟(给WhatsApp Web留加载时间)。
  3. 号码格式不规范:CSV中的号码可能包含空格、换行符等无效字符,导致格式不符合WhatsApp要求。
  4. 无错误捕获机制:代码没有异常捕获逻辑,即使pywhatkit内部出错,控制台也不会输出报错信息,无法定位问题。

解决方案

1. 用多线程避免GUI阻塞

将发送逻辑放到子线程中执行,防止阻塞Tkinter主线程:

import threading

def send_whatsapp_message():
    selected_numbers = numbers_listbox.curselection()
    message = message_entry.get()
    
    # 子线程执行发送逻辑
    def send_thread():
        for index in selected_numbers:
            number = numbers_listbox.get(index).strip().replace(' ', '')  # 清洗号码
            try:
                # 使用立即发送方法
                kit.sendwhatmsg_instantly(f'+{number}', message, wait_time=15)
            except Exception as e:
                print(f"发送失败到号码 {number}: {str(e)}")
        # 回到主线程清空输入框
        root.after(0, lambda: message_entry.delete(0, tk.END))
    
    # 启动子线程
    threading.Thread(target=send_thread, daemon=True).start()

2. 修正时间参数问题

  • 使用kit.sendwhatmsg_instantly()方法实现立即发送,该方法无需指定时间,只需设置等待时间(默认15秒,给WhatsApp Web加载时间)。
  • 若坚持使用sendwhatmsg,需传入当前时间并将分钟加1(pywhatkit要求至少1分钟准备时间):
    from datetime import datetime
    now = datetime.now()
    kit.sendwhatmsg(f'+{number}', message, now.hour, now.minute + 1)
    

3. 规范号码格式

读取CSV时清洗号码,去除多余字符:

def open_csv_file():
    file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
    if file_path:
        with open(file_path, 'r') as file:
            reader = csv.reader(file)
            for row in reader:
                if row[0]:
                    cleaned_number = row[0].strip().replace(' ', '')
                    numbers_listbox.insert(tk.END, cleaned_number)

4. 添加异常捕获

在发送逻辑中加入try-except块,打印错误信息便于排查:

try:
    kit.sendwhatmsg_instantly(f'+{number}', message)
except Exception as e:
    print(f"发送错误: {e}")

最终修改后的核心发送函数

import threading
from datetime import datetime

def send_whatsapp_message():
    selected_numbers = numbers_listbox.curselection()
    message = message_entry.get()
    
    def send_thread():
        for index in selected_numbers:
            number = numbers_listbox.get(index).strip().replace(' ', '')
            if not number:
                continue
            full_number = f'+{number}'
            try:
                kit.sendwhatmsg_instantly(full_number, message, wait_time=15)
                print(f"消息已发送到 {full_number}")
            except Exception as e:
                print(f"发送到 {full_number} 失败: {str(e)}")
        root.after(0, lambda: message_entry.delete(0, tk.END))
    
    threading.Thread(target=send_thread, daemon=True).start()

内容的提问来源于stack exchange,提问作者Daniele Intra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:09:51