使用Pywhatkit在Heroku部署WhatsApp机器人遇DISPLAY错误求助
问题背景
本地用Pywhatkit实现WhatsApp消息自动发送功能运行正常,但部署到Heroku平台后出现KeyError: 'DISPLAY'错误,导致脚本无法执行。
报错详情
Traceback (most recent call last):
File "/app/test.py", line 2, in
import pywhatkit
File "/app/.heroku/python/lib/python3.10/site-packages/pywhatkit/init.py", line 16, in
from pywhatkit.whats import (
File "/app/.heroku/python/lib/python3.10/site-packages/pywhatkit/whats.py", line 7, in
import pyautogui as pg
File "/app/.heroku/python/lib/python3.10/site-packages/pyautogui/init.py", line 249, in
import mouseinfo
File "/app/.heroku/python/lib/python3.10/site-packages/mouseinfo/init.py", line 223, in
_display = Display(os.environ['DISPLAY'])
File "/app/.heroku/python/lib/python3.10/os.py", line 679, in getitem
raise KeyError(key) from None
KeyError: 'DISPLAY'
现有配置文件
requirements.txt
pywhatkit==5.4
test.py
import pywhatkit try: pywhatkit.sendwhatmsg_instantly("+1*********", "Hello from NewYork") print("Successfully Sent!") except: print("An Unexpected Error!")
问题原因
Pywhatkit依赖pyautogui库实现鼠标键盘模拟操作,而pyautogui需要图形界面环境才能初始化。Heroku是无图形界面的服务器环境,未设置DISPLAY环境变量,导致依赖的mouseinfo库初始化失败。
解决方案
方案一:替换为非GUI依赖的WhatsAPI库(推荐)
放弃Pywhatkit,改用无需图形界面的WhatsApp官方API适配库,比如pywa,稳定性和可靠性更高:
- 更新requirements.txt:
pywa==5.0.0
- 修改test.py(需提前在Meta开发者平台注册WhatsApp Business账号,获取Phone ID和API令牌):
from pywa import WhatsApp # 初始化WhatsApp客户端 wa = WhatsApp( phone_id="你的Facebook应用Phone ID", token="你的WhatsApp Business API令牌" ) try: wa.send_message( to="+1*********", text="Hello from NewYork" ) print("Successfully Sent!") except Exception as e: print(f"Error: {e}")
方案二:为Heroku配置虚拟图形界面(兼容Pywhatkit)
通过虚拟显示环境模拟图形界面,让Pywhatkit可以正常运行:
- 添加Heroku虚拟显示构建包:
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-xvfb.git
- 更新requirements.txt:
pywhatkit==5.4 pyvirtualdisplay==3.0
- 修改test.py,在导入Pywhatkit前初始化虚拟显示:
from pyvirtualdisplay import Display # 启动虚拟显示 display = Display(visible=0, size=(800, 600)) display.start() import pywhatkit try: pywhatkit.sendwhatmsg_instantly("+1*********", "Hello from NewYork") print("Successfully Sent!") except Exception as e: print(f"An Unexpected Error: {e}") finally: # 关闭虚拟显示 display.stop()
注意:此方案依赖无头浏览器自动化,在Heroku环境中可能出现加载不稳定的情况。
内容的提问来源于stack exchange,提问作者Abraham

