Python技术迷

用 Python 实现对微信进行推送消息的工具 -- pushplus

有段时间我经常被自己写的脚本吓醒。

半夜三点,手机突然震一下,是某个爬虫崩了、某个定时任务没跑完,或者服务器磁盘又快满了。以前这些通知都是我自己写邮件、打 webhook,写来写去一堆重复代码,心情非常暴躁。

后来换成 pushplus 之后,基本就一个函数解决问题了,整个世界清净不少。

今天就用一个完整的小工具,讲一下怎么用 Python 把各种消息推到微信上去,用的就是 pushplus 这个服务。

先把 pushplus 是啥说清楚

简单讲,pushplus 就是一个“代发消息”的平台,它帮你对接好了微信、企业微信、邮件、钉钉、飞书之类的渠道,你这边只要调一个 HTTP 接口,把 token、标题、内容丢过去,它就负责送达。官方文档里,最常用的发送接口是 http://www.pushplus.plus/send,支持 GET 和 POST,两种都行,不过长内容官方也更建议用 POST

实际用的时候,你只关心这几个信息:

  • 你的用户 token(登录官网、关注公众号之后可以在个人中心看到)
  • 一个固定的接口地址
  • 要发的标题和内容
  • 可选的一些参数,比如模板类型、群组编码 topic、发送渠道 channel 等

所以整体思路就是:Python 里用 requests 调这个接口,包一层函数,之后任何脚本里想通知就调用一下。

环境准备一下

Python 版本随意,3.7 以上就很正常了,核心依赖就一个:

pip install requests

然后找个地方把你的 pushplus token 记下来,等等代码里要用,长得大概像一串 32 位的十六进制字符串。

写一个最小可用的推送函数

先来个能跑起来的最小版本,先不考虑各种异常和高级功能,思路就是:构造一个 JSON,POST 给 pushplus 的 send 接口。

import requests

PUSHPLUS_TOKEN = "替换成你自己的 token"

defpushplus_simple(content: str, title: str = "Python 通知"):
"""
    用 pushplus 推一条最简单的微信消息
    """

    url = "http://www.pushplus.plus/send"
    body = {
"token": PUSHPLUS_TOKEN,
"title": title,
"content": content,
# 不写 template 默认是 html,就先用默认的
    }

    resp = requests.post(url, json=body, timeout=10)
    resp.raise_for_status()
    data = resp.json()
# 文档里说 code=200 只代表“请求收到了”,真正是否送达是异步处理的:contentReference[oaicite:2]{index=2}
if data.get("code") == 200:
        print("pushplus 已接收请求,流水号:", data.get("data"))
else:
        print("pushplus 拒绝了请求:", data)

跑一行试试看:

if __name__ == "__main__":
    pushplus_simple("脚本跑完啦,耗时 3.21s", "测试推送")

如果你公众号关注好了,基本几秒钟微信上就能看到消息。

稍微专业一点:封装成一个小工具类

上面这个函数够用,但一旦你想支持群组、markdown、邮件渠道之类的,就会发现参数开始变多了。可以稍微封装一个类,后面在任何项目里直接 import 复用。

import json
import traceback
from typing import Optional, Dict, Any

import requests


classPushPlusClient:
"""
    一个简单的 pushplus 封装
    """


def__init__(
        self,
        token: str,
        base_url: str = "http://www.pushplus.plus/send",
        timeout: int = 10,
    )
:

        self.token = token
        self.base_url = base_url
        self.timeout = timeout

defsend(
        self,
        content: str,
        title: str = "Python 通知",
        template: str = "html",
        topic: Optional[str] = None,
        channel: Optional[str] = None,
        option: Optional[str] = None,
        to: Optional[str] = None,
        extra: Optional[Dict[str, Any]] = None,
    )
 -> Dict[str, Any]:

"""
        发送一条消息到 pushplus

        :param content: 消息正文
        :param title: 消息标题
        :param template: 模板类型,html/txt/json/markdown 等:contentReference[oaicite:3]{index=3}
        :param topic: 群组编码,不传就是发给自己
        :param channel: 发送渠道,比如 wechat/mail/webhook/cp 等:contentReference[oaicite:4]{index=4}
        :param option: 某些渠道需要的额外配置编码,比如企业微信机器人编码
        :param to: 好友 token(发给指定好友时用):contentReference[oaicite:5]{index=5}
        :param extra: 预留的一些扩展字段,比如 callbackUrl、timestamp 等
        """

        payload: Dict[str, Any] = {
"token": self.token,
"title": title,
"content": content,
"template": template,
        }

if topic:
            payload["topic"] = topic
if channel:
            payload["channel"] = channel
if option:
            payload["option"] = option
if to:
            payload["to"] = to
if extra:
            payload.update(extra)

try:
            resp = requests.post(
                self.base_url, json=payload, timeout=self.timeout
            )
            resp.raise_for_status()
            data = resp.json()
except Exception:
# 这里就别再推自己了,打印个本地日志就行
            traceback.print_exc()
return {"code": -1, "msg": "request error"}

# 按文档约定,code=200 表示“请求正常受理”,真正发没发出去需要看异步回调或者用流水号去查:contentReference[oaicite:6]{index=6}
return data

用法大概长这样:

client = PushPlusClient(token="你的 token")

# 发一个普通 html 消息
client.send("构建成功 ✅", title="CI 构建通知")

# 发一个 markdown 消息
md_content = """# 线上发布结果

- 版本:v1.2.3
- 状态:**成功**
- 耗时:15 分钟
"""

client.send(md_content, title="发版结果", template="markdown")

做一个“脚本异常就自动推送”的小工具

最常见的需求就是:脚本里一旦出错,就给自己发个微信,不然半夜炸了你第二天才知道。

可以写一个简单的装饰器,把异常捕获之后丢给 pushplus:

import functools
import traceback

push_client = PushPlusClient(token="你的 token")


defnotify_on_error(title: str = "脚本异常告警"):
"""
    把这个装饰器挂在任意函数上,一旦抛异常就微信通知
    """


defdecorator(func):
        @functools.wraps(func)
defwrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
                tb = traceback.format_exc()
                content = f"{func.__name__} 运行异常:{e}\n\n```python\n{tb}\n```"
# 用 markdown 模板,这样栈信息好看一点
                push_client.send(
                    content=content,
                    title=title,
                    template="markdown",
                )
# 异常再抛出去,看你业务需要
raise

return wrapper

return decorator

随便找个函数套上:

@notify_on_error("定时任务异常")
defsync_order_data():
# 模拟一下错误
    x = 1 / 0

这个函数每次炸掉的时候,你手机上就会收到一条类似这样的消息:标题“定时任务异常”,正文里是完整的 traceback,定位问题非常舒服。

顺便利用一下 json 模板做“小报表”

pushplus 有一个 json 模板,意思是你传过去的 content 是一段 JSON 字符串,它会按表格风格帮你排一下版,比纯文本好看很多。

比如每天把爬虫成功/失败数量、耗时之类的统计一下,发一个小日报:

from datetime import datetime


defsend_daily_report():
    report = {
"date": datetime.now().strftime("%Y-%m-%d"),
"spider": "job_spider",
"total": 1234,
"success": 1200,
"failed": 34,
"avg_ms": 85,
    }

    content = json.dumps(report, ensure_ascii=False)

    push_client.send(
        content=content,
        title="爬虫日报",
        template="json",  # 让 pushplus 按 json 模板渲染:contentReference[oaicite:8]{index=8}
    )

你会在微信里看到一块类似“字段-值”的结构化展示,比截图发送、美化日志都省事。

如果要群发同事,看下 topic 的用法

自己一个人玩还好,如果你想把消息推给一整个小组,比如“后端技术群”,可以用 pushplus 的群组功能,对应参数叫 topic。

大致流程是:

  • 在 pushplus 官网创建一个群组,拿到一个群组编码(topic)
  • 把同事拉进这个群
  • 代码里把 topic 传进去,消息就会群发给这批人

代码其实跟刚才没啥区别,多传个参数而已:

defsend_team_deploy_msg(ok: bool, topic: str):
    status = "成功 ✅"if ok else"失败 ❌"
    content = f"新版本发布{status}"

    push_client.send(
        content=content,
        title="发布结果通知",
        topic=topic,         # 群组编码
        template="html",
    )

这样一来,CI/CD 跑完之后,整个小组手机上一起震一下,谁也跑不掉。

多渠道的事简单提一嘴

有时候你希望除了微信,还顺便发个企业微信机器人或者邮件,这个在 pushplus 里叫“多渠道”,参数是 channel 和 option。

比如你已经在 pushplus 里配置好了一个企业微信机器人,编码叫 pushplus,那大概是这样:

defsend_to_wechat_robot(msg: str):
    push_client.send(
        content=msg,
        title="机器人测试",
        channel="webhook",  # 指定走 webhook 渠道:contentReference[oaicite:12]{index=12}
        option="pushplus",  # 你在控制台配置的渠道编码
        template="markdown",
    )

邮件、企业微信应用这些也类似,只是 channel、option 的取值不一样,文档里都有列。

最后几个小细节,踩坑少一点

这个工具写完基本就能一直复用了,不过有几个小点提一下,免得你以后骂它:

  • 内容很长的时候,尽量用 POST,不要偷懒用 GET,那样 URL 可能会被浏览器或中间代理砍掉一截。
  • code == 200 不代表消息百分百送达,只能说明 pushplus 服务端收到了你的请求,真正的失败/成功是异步处理的,如果你业务很关键,可以配一下 callbackUrl 或者用流水号再查一次结果。
  • 记得设个合理的 timeout,不要让你的业务线程被一个网络抖动拖死;上面的例子里我用了 10 秒,你可以按场景自己调。
  • token 别写死在公开仓库里,最起码搞个环境变量或者配置文件忽略掉。

基本就这些了,你把上面这几个函数拷到自己项目里,改好 token 和一点点业务文案,日常脚本、定时任务、监控告警,通通可以一键推到微信上。

至于推的太多会不会被同事拉黑,那就另说了…

-END-

我为大家打造了一份RPA教程,完全免费:songshuhezi.com/rpa.html

🔥虎哥私藏精品🔥

虎哥作为一名老码农,整理了全网最全《python高级架构师资料合集》,总量高达650GB