惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
D
Docker
腾讯CDC
J
Java Code Geeks
大猫的无限游戏
大猫的无限游戏
The Cloudflare Blog
Martin Fowler
Martin Fowler
MongoDB | Blog
MongoDB | Blog
博客园 - Franky
博客园 - 三生石上(FineUI控件)
Recent Announcements
Recent Announcements
F
Fortinet All Blogs
IT之家
IT之家
WordPress大学
WordPress大学
M
MIT News - Artificial intelligence
爱范儿
爱范儿
Microsoft Azure Blog
Microsoft Azure Blog
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
N
Netflix TechBlog - Medium
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
博客园 - 【当耐特】

博客园 - 大汪的数据之路

外企的问卷调查 10 Tips On How To Be Exceptional In Anything You Do(在所做的任何事情上变得卓越的10个方法) 企业网络环境全景解析——面向AI智能数据分析场景的数据工程师指南 数据虚拟化技术解析:从概念到实践 数据虚拟化:从“搬运数据”到“连接数据”的范式革命 数据运维值班预警自动化 数据“搬砖”实战经验 星环大数据使用体验 vibe coding使用体验 基于SQL实现分组的文字排序聚合 数据码农马年大吉 字符串分割并展开成表格的SQL实现方法 BI报表及可视化分析类工具使用经验总结(下) BI报表及可视化分析类工具使用经验总结(上) Chat2DB测试体验 常用数据管理工具与平台汇总 OneID系统建设实践总结 网易有数BI使用总结 网易NDH大数据平台使用经验 版本管理总结 程序自动化vs人工手动处理 SQL开发总结 数据平台使用经验 数据团队运维值班任务简介 Python环境安装、管理与部署 windows获取kerberos认证 SQL动态长度行列转置 ODI Scenario 场景 Oracle KEEP 分析函数
基于Python实现自动化微信通知和预警
大汪的数据之路 · 2025-12-18 · via 博客园 - 大汪的数据之路

一、背景:

作为IT系统值班人员,可能会出现如下工作场景:

每日早晨定时(如早晨6点)检查某系统是否运行正常或者某夜间任务运行是否运行成功。

  1. 若系统正常或成功执行,则给某微信群发送“系统运行成功“类似字样的消息,这样群里的领导和同事就能看到当日系统的状态。
  2. 若系统异常或执行失败,则排查问题并尝试解决,解决完问题之后可以在群里通报问题及解决方法。

一般常规方法是值班人员设置定时闹钟,到点起床后登录系统进行检查,然后发送消息或者处理报错。在系统上线早期时,由于出问题的频率较高,该方案可靠性高,较多被采用。然当系统运行一定周期后,会相对较稳定,出错概率较小(如低于10%),每天定时起床并登录到系统进行人工检查就显得有些低效。此时可以尝试用一些自动化方案来解决。

二、自动化方案:

  Python语言功能强大,上手容易,非常适合做此类自动化任务。具体实现方法如下:定时读取系统后台的数据库表来判断系统的状态。若正常则直接发消息至某微信群,若异常则拨打当日值班人员的微信电话,提醒其登录系统排查问题。

  1. 核心模块:pyautogui,模拟人工鼠标和键盘操作。
  2. 重要功能:locateCenterOnScreen,利用该图像识别方法可以匹配界面中某个区域,比如需要点击微信聊天框中的“电话”图标。

三、代码实现:

以下为python调用微信的代码(发送消息或者拨打电话)。已实测并上线运行。

import pyperclip
import pyautogui
import time
import show_mouse

def locate_tpl(tpl_path, confidence=0.8):
    """模板匹配 -> 返回屏幕绝对坐标"""
    pos = pyautogui.locateCenterOnScreen(tpl_path, confidence=confidence)
    # pos = pyautogui.locateCenterOnScreen(tpl_path)
    if pos is None:
        raise RuntimeError(f'未找到模板 {tpl_path},请确认微信已置顶并重新截图')
    return pos

def open_app_by_search(app_name: str):
    """查找软件并打开"""
    # 1. 按 Win 键呼出开始菜单
    pyautogui.press('win')
    time.sleep(0.5)

    # 2. 输入软件名
    pyautogui.write(app_name, interval=0.1)
    time.sleep(0.1)

    # 3. 回车打开(默认第一项就是)
    pyautogui.press('enter')
    time.sleep(1)          # 给软件启动留时间

def record_active_window():
    """返回当前活动窗口的坐标+尺寸 dict"""
    win = pyautogui.getActiveWindow()     # 当前获得焦点的窗口
    return {
        'title': win.title,
        'left': win.left,
        'top': win.top,
        'width': win.width,
        'height': win.height,
        'box': (win.left, win.top, win.width, win.height)  # region 直接可用
    }
def search_friend_and_open_chatbox(sw_posi_info, friend):
    """搜索某个联系人或者群并打开聊天窗口"""
    # 1. 获取微信左上角输入框位置
    search_input_x = sw_posi_info['left'] + 150
    search_input_y = sw_posi_info['top'] + 32

    # 2. 点击输入框
    pyautogui.click(search_input_x, search_input_y)
    show_mouse.click_with_ring(search_input_x, search_input_y)

    # 3. 输入好友昵称并回车搜索(用 pyperclip 避免中文输入乱码)
    pyperclip.copy(friend)
    pyautogui.hotkey("ctrl", "v")
    time.sleep(1)
    pyautogui.press("enter")
    time.sleep(2)
    
def send_wechat_msg(friend, send_msg):
    """给某个微信好友或者微信群发消息"""
    # 1. 打开微信
    open_app_by_search('weixin')
    pyautogui.press("enter")
    time.sleep(2)

    # 2. 获取软件的坐标
    sw_posi_info = record_active_window()
    #print(sw_posi_info)

    # 3. 搜索联系人并打开聊天框
    search_friend_and_open_chatbox(sw_posi_info, friend)

    # 4. 找到消息输入框,并点击获取焦点
    send_button_x = sw_posi_info['left'] + sw_posi_info['width'] - 100
    send_button_y = sw_posi_info['top'] + sw_posi_info['height'] - 100
    pyautogui.click(send_button_x, send_button_y)
    show_mouse.click_with_ring(send_button_x, send_button_y)

    # 5. 粘贴要发送的消息
    pyperclip.copy(send_msg)
    pyautogui.hotkey("ctrl", "v")
    time.sleep(0.3)

    # 6. 点击发送按钮
    send_button_x = sw_posi_info['left'] + sw_posi_info['width'] - 100
    send_button_y = sw_posi_info['top'] + sw_posi_info['height'] - 32
    pyautogui.click(send_button_x, send_button_y)
    show_mouse.click_with_ring(send_button_x, send_button_y)

def send_wechat_call(friend):
    """给某个微信好友打微信电话"""

    # 1. 打开微信
    open_app_by_search('weixin')
    pyautogui.press("enter")
    time.sleep(2)

    # 2. 获取软件的坐标
    sw_posi_info = record_active_window()
    #print(sw_posi_info)

    # 3. 搜索联系人并打开聊天框
    search_friend_and_open_chatbox(sw_posi_info, friend)

    # 4. 搜索打电话图标的位置
    call_pic = 'wechat_call_pic.png'  # 提前截图准备好的打电话图标
    call_pic_x, call_pic_y = locate_tpl(call_pic)
    #print(call_pic_x)
    #print(call_pic_y)

    # 5. 点击图标并拨打电话
    pyautogui.click(call_pic_x, call_pic_y)
    show_mouse.click_with_ring(call_pic_x, call_pic_y)

call_wechat

import tkinter as tk

def click_with_ring(x, y, r=30, ms=400):
    """在 (x,y) 画一个逐渐消失的圆环,模拟点击特效"""
    root = tk.Tk()
    root.overrideredirect(True)          # 无边框
    root.attributes('-topmost', True)    # 置顶
    root.attributes('-transparentcolor', 'white')  # 白色全透明
    root.geometry(f'{r*2}x{r*2}+{x-r}+{y-r}')

    c = tk.Canvas(root, bg='white', highlightthickness=0)
    c.pack(fill='both', expand=True)
    ring = c.create_oval(2, 2, r*2-2, r*2-2, outline='red', width=3)

    def fade(alpha=255):
        if alpha <= 0:
            root.destroy()
            return
        c.itemconfig(ring, fill='#%02x0000' % alpha)
        root.after(int(ms/15), fade, alpha-17)
    fade()
    root.mainloop()

show_mouse

四、注意点&Tips:

  1. 搜索微信群名时,用拼音即可直接定位群名,而用中文反而无法直接定位群(中文搜索可以直接定位好友,群需要再手动选择,多了一步操作)。
  2. pyautogui运行时,Python脚本后台进程会与前台操作争抢输入(鼠标及键盘),因此代码中要适时的加入一些等待,避免Python后台进程干扰前台操作。
  3. 该方案与uiautomation/PyOfficeRobot等框架方案相比,pyautogui是模拟人来操作,实际运行一段时间后,在低频操作场景下,微信客户端被系统后台检核到并自动退出的概率较小。
  4. 利用图像识别算法匹配区域时,如果使用confidence参数,需要额外安装opencv库