【自动化】wxauto包操作微信自动化

1、需求说明

希望能实现自动化加V,但又不能让使用者知道具体的手机号,确保隐私;另外,这里未进行封装和对接,仅一个DEMO。

效果示例【窗口有一个遮羞/遮挡功能】:

2、相关依赖

import wxauto

import sys, os, win32gui, win32con, win32api, subprocess, time

import pyautogui

import uiautomation as uia

from pynput import mouse, keyboard

import wx

这些库提供了对微信窗口的控制、自动化操作以及系统级别的事件监听(如鼠标和键盘)等功能。

3、相关功能

(1)事件监听模块 (EventListener)

代码中定义了 EventListener 类,用于检测用户的干预行为(鼠标或键盘操作),从而在脚本运行中可以及时停止。这个类实现了一个事件监听器,主要用于捕捉用户是否有鼠标或键盘操作:


# 监听鼠标和键盘事件,用于检测用户的干预行为
class EventListener:
    def __init__(self):
        self.mouse_listener = mouse.Listener(on_move=self.on_move, on_click=self.on_click, on_scroll=self.on_scroll)
        self.keyboard_listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
        self.interrupted = False

    # 启动监听器
    def start(self):
        self.mouse_listener.start()
        self.keyboard_listener.start()

    # 停止监听器
    def stop(self):
        self.mouse_listener.stop()
        self.keyboard_listener.stop()

    # 当鼠标移动时,触发中断
    def on_move(self, x, y):
        self.interrupt()

    # 当鼠标点击时,触发中断
    def on_click(self, x, y, button, pressed):
        self.interrupt()

    # 当鼠标滚轮滚动时,触发中断
    def on_scroll(self, x, y, dx, dy):
        self.interrupt()

    # 当键盘按下时,触发中断
    def on_press(self, key):
        self.interrupt()

    # 当键盘释放时,触发中断
    def on_release(self, key):
        self.interrupt()

    # 中断处理函数
    def interrupt(self):
        if not self.interrupted:
            self.interrupted = True
            print("检测到用户干预,停止脚本运行。")
            sys.exit(0)

 (2)微信遮罩窗口模块 (MaskWindow)

在微信窗口上创建一个透明的具备鼠标穿透功能的遮罩窗口,以避免用户不小心干扰到窗口内部操作:

  • 初始化遮罩窗口:获取微信窗口的坐标和大小,然后创建一个透明的遮罩窗口并设置其位置与微信窗口一致。
  • SetMouseThrough:设置鼠标穿透功能,确保遮罩窗口不会阻挡用户鼠标对微信窗口的操作。
  • close:用于关闭遮罩窗口。

# 创建微信窗口大小的遮罩窗口
class MaskWindow(wx.Frame):
    def __init__(self, hwnd):
        # 获取微信窗口的坐标和大小
        rect = win32gui.GetWindowRect(hwnd)
        x, y, width, height = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]

        # 创建透明的遮罩窗口
        wx.Frame.__init__(self, None, style=wx.NO_BORDER | wx.STAY_ON_TOP)
        self.SetPosition((x, y))
        self.SetSize((width, height))
        self.SetTransparent(200)  # 设置透明度,值范围0-255
        self.Show()
        self.SetMouseThrough(True)

    # 设置鼠标穿透功能
    def SetMouseThrough(self, through=True):
        hwnd = self.GetHandle()
        ex_style = win32api.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
        if through:
            ex_style |= win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
        else:
            ex_style &= ~(win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT)
        win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, ex_style)

    def GetHandle(self):
        return self.Handle  # 直接使用self.Handle以获取窗口句柄

    def close(self):
        self.Close()

(3)微信启动及窗口检测模块 (StartWeChat)

(4)添加好友功能模块 (AddNewFriend)

4、完整代码

import wxauto
import sys, os, win32gui, win32con, win32api, subprocess, time
import pyautogui
import uiautomation as uia
from pynput import mouse, keyboard
import wx

# 监听鼠标和键盘事件,用于检测用户的干预行为
class EventListener:
    def __init__(self):
        self.mouse_listener = mouse.Listener(on_move=self.on_move, on_click=self.on_click, on_scroll=self.on_scroll)
        self.keyboard_listener = keyboard.Listener(on_press=self.on_press, on_release=self.on_release)
        self.interrupted = False

    # 启动监听器
    def start(self):
        self.mouse_listener.start()
        self.keyboard_listener.start()

    # 停止监听器
    def stop(self):
        self.mouse_listener.stop()
        self.keyboard_listener.stop()

    # 当鼠标移动时,触发中断
    def on_move(self, x, y):
        self.interrupt()

    # 当鼠标点击时,触发中断
    def on_click(self, x, y, button, pressed):
        self.interrupt()

    # 当鼠标滚轮滚动时,触发中断
    def on_scroll(self, x, y, dx, dy):
        self.interrupt()

    # 当键盘按下时,触发中断
    def on_press(self, key):
        self.interrupt()

    # 当键盘释放时,触发中断
    def on_release(self, key):
        self.interrupt()

    # 中断处理函数
    def interrupt(self):
        if not self.interrupted:
            self.interrupted = True
            print("检测到用户干预,停止脚本运行。")
            sys.exit(0)

# 创建微信窗口大小的遮罩窗口
class MaskWindow(wx.Frame):
    def __init__(self, hwnd):
        # 获取微信窗口的坐标和大小
        rect = win32gui.GetWindowRect(hwnd)
        x, y, width, height = rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1]

        # 创建透明的遮罩窗口
        wx.Frame.__init__(self, None, style=wx.NO_BORDER | wx.STAY_ON_TOP)
        self.SetPosition((x, y))
        self.SetSize((width, height))
        self.SetTransparent(200)  # 设置透明度,值范围0-255
        self.Show()
        self.SetMouseThrough(True)

    # 设置鼠标穿透功能
    def SetMouseThrough(self, through=True):
        hwnd = self.GetHandle()
        ex_style = win32api.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
        if through:
            ex_style |= win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT
        else:
            ex_style &= ~(win32con.WS_EX_LAYERED | win32con.WS_EX_TRANSPARENT)
        win32api.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, ex_style)

    def GetHandle(self):
        return self.Handle  # 直接使用self.Handle以获取窗口句柄

    def close(self):
        self.Close()

# 启动微信,并返回微信对象和窗口句柄
def StartWeChat(chatroom):
    try:
        Wx = wxauto.WeChat()
        win = win32gui.FindWindow('WeChatMainWndForPC', chatroom)
        if win != 0:
            win32gui.ShowWindow(win, win32con.SW_SHOWNORMAL)
            win32gui.SetForegroundWindow(win)
        print('微信已启动成功')
        return Wx, win
    except:
        print(f'找不到【{chatroom}】窗口,尝试启动微信...')
        wechat_path = r"C:\Program Files\Tencent\WeChat\WeChat.exe"
        if os.path.exists(wechat_path):
            subprocess.Popen(wechat_path)
            time.sleep(5)
            win = win32gui.FindWindow('WeChatMainWndForPC', chatroom)
            if win != 0:
                print("微信已启动并找到窗口")
                win32gui.ShowWindow(win, win32con.SW_SHOWNORMAL)
                win32gui.SetForegroundWindow(win)
            else:
                print("仍无法找到微信窗口,请检查路径和微信是否正常启动")
                sys.exit(0)
        else:
            print("微信路径无效,请检查路径是否正确")
            sys.exit(0)
        return None

# 关闭空白提示窗口
def close_NullWindow():
    UiaAPI = uia.WindowControl(ClassName='WeChatMainWndForPC', searchDepth=1)
    windows = UiaAPI.GetChildren()
    for window in windows:
        try:
            if window.Name == "":
                window.SetActive()
                pyautogui.hotkey('alt', 'f4')
            if "无法找到该用户,请检查你填写的账号是否正确" in window.Name:
                print("找到提示信息: 无法找到该用户,请检查你填写的账号是否正确")
        except Exception as e:
            print(f"访问窗口失败或关闭失败: {e}")

# 添加微信好友
def AddNewFriend(phone, addmsg, remark, tags):
    try:
        close_NullWindow()
        wechat.SwitchToChat()
        time.sleep(1)

        print(f"添加好友,手机号: {phone}")
        wechat.AddNewFriend(phone, addmsg=addmsg, remark=remark, tags=tags)

    except LookupError as e:
        if "Find Control Timeout" in str(e):
            print(f"{phone} 已是好友,跳过添加")
            close_NullWindow()
        else:
            print(f"发生意外错误: {e}")
            close_NullWindow()
    except Exception as e:
        print(f"添加好友时出错: {e}")
        close_NullWindow()

# 主程序入口
if __name__ == "__main__":
    listener = EventListener()
    listener.start()

    app = wx.App(False)

    # 启动微信并获取句柄
    wechat, hwnd = StartWeChat("微信")
    print(wechat, hwnd)
    if wechat and hwnd:
        # 创建与微信窗口大小相同的遮罩窗口
        mask_window = MaskWindow(hwnd)

        # 添加好友的手机号列表
        phones = ['1111111111111']
        addmsg = '申请语'  # 添加好友的消息
        remark = '备注'
        tags = ['*******']

        for phone in phones:
            if listener.interrupted:
                break
            AddNewFriend(phone, addmsg, remark, tags)
            time.sleep(1)

        # 切换至微信主界面
        wechat.SwitchToChat()

    # 等待用户干预
    while not listener.interrupted:
        time.sleep(0.1)

    # 当检测到中断时,关闭遮罩窗口并退出程序
    mask_window.close()
    listener.stop()
    sys.exit(0)

【免责声明】本文章内容仅供个人学习、研究和欣赏之用,严禁用于任何商业用途。另内容未经授权,禁止转载或用于商业用途。如有侵权行为,请及时联系及处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值