环境:windows11,微信3.9.10,python3.12

安装模块:pip install uiautomation pyautogui

具体窗口定位可以使用inspect.exe查看,一般位于C:\Program Files (x86)\Windows Kits\10\bin下的文件夹,选择x86版本的就行

import uiautomation as auto
import os
from time import sleep
import pyautogui


class WechatAuto:

    def __init__(self, wechat_locate: str):
        """
        启动微信,定位基本元素
        :param wechat_locate: 微信安装绝对路径.exe
        """
        os.system(rf'start {wechat_locate}')
        self.wechat_window = auto.WindowControl(searchDepth=1, ClassName='WeChatMainWndForPC')
        # 窗口控制栏,固定,最大小化,退出
        self.window_control = self.wechat_window.ToolBarControl(searchDepth=5, LocalizedControlType="工具栏")
        # 用户导航:用户,聊天,通讯录,收藏……
        self.guide_tool = self.wechat_window.ToolBarControl(searchDepth=4, Name='导航')
        # 会话列表
        self.chat_list = self.wechat_window.ListControl(searchDepth=8, Name='会话')
        # 当前聊天对象消息列表窗口,聊天内容
        self.chat_massage = self.wechat_window.ListControl(searchDepth=13, Name='消息')

        # 聊天界面搜索框
        self.chat_search = self.wechat_window.EditControl(searchDepth=7, Name='搜索')
        # 先清除搜索框再输入内容
        self.chat_search_clear = self.wechat_window.ButtonControl(searchDepth=7, Name='清空')
        # 搜索结果
        self.search_result = self.wechat_window.ListControl(searchDepth=8, Name="@str:IDS_FAV_SEARCH_RESULT:3780",
                                                            LocalizedControlType="列表")

        # 发送按钮
        self.send_button = self.wechat_window.ButtonControl(searchDepth=15, Name="发送(S)")

        self.chat_name: str = ""

    def input_content(self, name: str):
        return self.wechat_window.EditControl(searchDepth=14, LocalizedControlType="编辑", Name=name)

    def searchFriend(self, name: str, where: str = "聊天") -> list:
        """
        从聊天列表查找聊天对象
        :param name: 聊天对象名称
        :param where: 查找位置=聊天/通讯录
        :return:
        """
        where_index: int = 0
        match where:
            case "聊天":
                where_index = 1
            case "通讯录":
                where_index = 2
            case _:
                print("invalid value")
                return [0, 0]
        # 定位聊天列表
        try:
            chat_list = self.guide_tool.GetChildren()[where_index]
            assert chat_list.Name, where
            chat_list.Click()
        except AssertionError:
            print("can not locate the contacts element,check with the Wechat version and try again,or the wrong "
                  "name about your friend")
            return [0, 0]
        except Exception as err:
            print(err)
            return [0, 0]
        # 定位搜索框
        try:
            check = self.chat_search.Name
            assert check=="搜索"
        except AssertionError:
            print("can not find the search element,check with the Wechat version and try again")
            return [0, 0]
        except Exception as err:
            print(err)
            return [0, 0]

        # 从聊天列表中查找聊天对象
        self.chat_search.Click()
        self.chat_search_clear.Click()
        self.chat_search.Click()
        self.chat_search.SendKeys(text=name, waitTime=0.2)
        try:
            assert self.search_result.GetChildren()[1], name
        except AssertionError:
            print("can not find the element in chet list,search in from contact")
            return [0, 0]
        except Exception as err:
            print(err)
            return [0, 0]

        return [1, self.search_result.GetChildren()[1]]

    def chatWithSomeone(self, name: str, massage: str) -> int:
        """
        查找聊天对象,定位到聊天输入框
        :param name: 聊天对象名称
        :param massage: 聊天发送信息
        :return: 成功返回1
        """
        if name != self.chat_name:
            chat_with = self.searchFriend(name)
            if chat_with[0] == 0:
                chat_with = self.searchFriend(name, where="通讯录")
            if chat_with[0] == 0:
                print(f"can not find your friend name {name}")
                return 0
            chat_with[1].Click()
            self.chat_name = name
        content = self.input_content(name)
        content.Click()
        content.SendKeys(text=massage, waitTime=0.2)
        self.send_button.Click()

        return 1

    def autoAddFriend(self, auto_add: bool = False):
        """
        开启自动添加好友申请
        :param auto_add: 是True,否False
        :return: str,添加的好友名称
        """
        pass

    def autoChatBaseOnContent(self, question_answer: dict[str, str]):
        """
        根据内容回循环复所有聊天
        :param question_answer: 聊天内容:回复内容,如果朋友向我发送的内容包含在【聊天内容】中,则使用【回复内容】进行回复
        :return: None
        """
        friend_question: dict[str, str] = {}
        for chat in self.chat_list.GetChildren():
            chat_name = chat.TextControl(searchDepth=5, foundIndex=1).Name
            chat_last_content = chat.TextControl(searchDepth=5, foundIndex=3).Name
            friend_question[chat_name] = chat_last_content
        qus = question_answer.keys()

        for friend in friend_question:
            # 这里是包含关系,也可以使用【jieba】模块进行词语解析
            my_answer = [question_answer[j] for j in qus if j in friend_question[friend]]
            for answer in my_answer:
                if answer != friend_question[friend]:
                    self.chatWithSomeone(name=friend, massage=answer)
                    friend_question[friend] = answer

    @staticmethod
    def setFileToClipBoard(file_path: str) -> int:
        """
        ui自动化,将文件复制到剪贴板中
        :param file_path: 文件绝对地址
        :return: 复制城成功返回1
        """
        if not os.path.exists(file_path):
            return 0
        father_path = os.path.abspath(os.path.join(file_path, os.pardir))
        file_name = file_path.split("\\")[-1]
        window_name = father_path.split("\\")[-1]
        try:
            os.system(rf"start explorer {father_path}")
            explorer = auto.WindowControl(searchDepth=1, ClassName="CabinetWClass", Name=window_name)
            file_locate = explorer.ListItemControl(searchDepth=8, Name=file_name, LocalizedControlType="项目列表")
            sleep(1)
            file_locate.Click(simulateMove=True, waitTime=0.2)
            close = auto.ButtonControl(searchDepth=4, Name="关闭")
            pyautogui.hotkey('ctrl', 'c')
            close.Click()
        except Exception as err:
            print(err)
            return 0
        return 1

    def sendFileToSomeone(self, name: str, file_path: str) -> int:
        """
        发送文件给某人
        :param name: 发送对象
        :param file_path: 文件路径
        :return:
        """
        check_friend = self.searchFriend(name)
        if check_friend[0] == 0:
            print(f"can not find your friend name {name}")
            return 0
        check_file = self.setFileToClipBoard(file_path)
        if check_file == 0:
            print(f"on such file {file_path}")
            return 0
        check_friend[1].Click()
        content = self.input_content(name)
        content.Click()
        pyautogui.hotkey('ctrl', 'v')
        self.send_button.Click()
        return 1


if __name__ == '__main__':
    wechat = WechatAuto(r"C:\AppInstall\WeChat\WeChat.exe")

    wechat.chatWithSomeone("文件传输助手", "112223345")

注:自动回复有可能会被微信判定为违规,有封号风险,谨慎使用!

Logo

一站式 AI 云服务平台

更多推荐