用企业微信机器人API发消息前必须确认:①webhook地址无多余空格/换行且权限已开启;②消息体为application/json格式并正确处理中文与NaN;③发送逻辑含异常捕获、超时设置及日志记录。

用企业微信机器人API发消息前必须确认的三件事
企业微信机器人不是直接发消息就能成功的,webhook 地址本身带签名限制,且默认只接受 POST 请求、application/json 格式。常见失败现象是返回 400 Bad Request 或 403 Forbidden,往往因为:
-
webhookURL 末尾多了空格或换行(复制时容易带入) - 消息体里用了中文但没加
json.dumps(..., ensure_ascii=False) - 企业微信后台没开启「群机器人」权限,或该机器人已被禁用/删除
发送前先用最简 payload 测试通不通:
curl -X POST "https://qyapi.weixin.qq.com/...your-webhook..." \
-H 'Content-Type: application/json' \
-d '{"msgtype": "text", "text": {"content": "test ok"}}'pandas.DataFrame 转成可读性强的文本消息(非图片)
微信群不支持直接发 Excel 或 HTML 表格,但企业微信机器人支持 markdown 和 text 两类格式。用 markdown 更清晰,关键是控制列宽和对齐,避免字段过长撑爆手机屏幕。
推荐做法是:用 df.to_string() 生成紧凑文本,再包进 markdown 的代码块;或用 df.to_markdown(index=False)(需安装 tabulate),但要注意:
立即学习“Python免费学习笔记(深入)”;
-
to_markdown默认会把 NaN 显示为nan,建议先df.fillna("-") - 列名含下划线(如
user_id)在 markdown 表格里会被识别为强调语法,得转义成user_id - 行数太多时,企业微信会截断(实测超 20 行大概率被砍),得提前
df.head(15)
示例片段:
import pandas as pd text = "? 日报摘要\n\n```" + df.head(10).to_string(index=False, max_colwidth=15) + "```"
用 schedule + requests 实现每天固定时间触发
不要用 time.sleep() 死等,也不要用系统 cron 配 Python 脚本(路径、环境变量易出错)。schedule 库轻量、可读性好,配合一个 while 循环就足够:
-
schedule.every().day.at("09:00").do(send_report)是标准写法,注意时间是本地时区,不是 UTC - 必须在循环里调用
schedule.run_pending(),否则不会执行 - 加
time.sleep(60)防止 CPU 空转,但别设太长(比如 3600),否则可能错过整点
关键结构:
import schedule
import time
<p>def send_report():
df = pd.read_csv("report.csv") # 或从数据库读
msg = build_message(df)
requests.post(webhook_url, json=msg)</p><p>schedule.every().day.at("08:30").do(send_report)</p><p>while True:
schedule.run_pending()
time.sleep(60)运行脚本时最容易被忽略的权限与稳定性问题
脚本跑在服务器上,不是本地电脑,几个硬性条件常被跳过:
- Linux 下用
nohup python report.py &启动后,进程没有父进程守护,SSH 断开后可能被 kill,建议改用systemd或supervisord - 企业微信接口有频率限制:
20 条/分钟,如果日报逻辑出错反复重试,很快被限流,得加异常捕获和退避 -
requests不带超时参数(timeout=10)的话,网络抖动会导致整个定时器卡住,后续任务全堆积
真正上线前,至少补上:
-
try/except requests.RequestException包裹发送逻辑 - 日志写入文件(别只 print),方便查哪天没发成功
-
df数据源加存在性判断,空数据也得发个“今日无新数据”占位,否则运营同学会以为挂了
企业微信机器人不支持撤回,发错就得手动爬楼解释——所以测试期务必用测试群,别一上来就怼到正式运营群。



















