【SXVD-016】女教師の秘蜜 佐藤あい python死亡UI完结桌面微信自动化

栏目分类【SXVD-016】女教師の秘蜜 佐藤あい python死亡UI完结桌面微信自动化

你的位置:萝莉少女 > 快播伦理电影在线观看 >

【SXVD-016】女教師の秘蜜 佐藤あい python死亡UI完结桌面微信自动化

发布日期:2024-08-24 05:29    点击次数:165

【SXVD-016】女教師の秘蜜 佐藤あい python死亡UI完结桌面微信自动化

配景【SXVD-016】女教師の秘蜜 佐藤あい

欧美色色

使用 wxpy 大约 itchat 这种第三方库通过Python死亡我方的微信号,完结好多自动化操作,用的是微信网页版接口,不外跟着微信的发展(信息安全等方面更加蹙迫,这种不合适官方祈望出现的东西,很容易就歇业。也由于itchat在 python 的 request 请求中,使用到的 headers 齐口舌常简便的 headers。何况平素诓骗到config.USER_AGENT ,被发现怀疑用剧本封号是诚然的

是以我算计打算用wxauto,用UI控件的体式操作微信

(uiautomation完结)

图片

wxauto第三方库先容

wxauto是某GitHub某位开源的

https://github.com/cluic/wxauto

功能很基础,毕竟是UI控件,完结的功能有

(1)群发音问包括图片,文献

(2)自动恢复和添加好友(有小bug,简便修改一下就行)

(3) 监控群聊东说念主员大约个东说念主聊天框

(4)赢得微信好友昵称等信息(有bug,我改了一下没生效)

恶果如下

图片

wxauto.py代码
'''Author: CluicUpdate: 2024-03-10Version: 3.9.8.15''' import uiautomation as uiafrom .languages import *from .utils import *from .elements import *from .errors import *from .color import *import datetimeimport timeimport osimport retry:    from typing import Literalexcept:    from typing_extensions import Literal class WeChat(WeChatBase):    def __init__(self, language='cn') -> None:        '''微信UI自动化实例        Args:            language (str, optional): 微信客户端言语版块, 可选: cn简体中语  cn_t繁体中语  en英文, 默许cn, 即简体中语        '''        self.VERSION = '3.9.8.15'        self.language = language        self.lastmsgid = None        self.listen = dict()        self._checkversion()        self.UiaAPI = uia.WindowControl(ClassName='WeChatMainWndForPC', searchDepth=1)        self._show()        self.SessionItemList = []        MainControl1 = [i for i in self.UiaAPI.GetChildren() if not i.ClassName][0]        MainControl2 = MainControl1.GetChildren()[0]        # 三个布局,导航栏(A)、聊天列表(B)、聊天框(C)        # _______________        # |■|———|    -□×|        # | |———|       |        # |A| B |   C   |   <--- 微信窗口布局简图暗示        # | |———|———————|        # |=|———|       |        # ———————————————        self.NavigationBox, self.SessionBox, self.ChatBox  = MainControl2.GetChildren()                # 开动化导航栏,以A开首 | self.NavigationBox  -->  A_xxx        self.A_MyIcon = self.NavigationBox.ButtonControl()        self.A_ChatIcon = self.NavigationBox.ButtonControl(Name=self._lang('聊天'))        self.A_ContactsIcon = self.NavigationBox.ButtonControl(Name=self._lang('通信录'))        self.A_FavoritesIcon = self.NavigationBox.ButtonControl(Name=self._lang('保藏'))        self.A_FilesIcon = self.NavigationBox.ButtonControl(Name=self._lang('聊天文献'))        self.A_MomentsIcon = self.NavigationBox.ButtonControl(Name=self._lang('一又友圈'))        self.A_MiniProgram = self.NavigationBox.ButtonControl(Name=self._lang('小要领面板'))        self.A_Phone = self.NavigationBox.ButtonControl(Name=self._lang('手机'))        self.A_Settings = self.NavigationBox.ButtonControl(Name=self._lang('开采相配他'))                # 开动化聊天列表,以B开首        self.B_Search = self.SessionBox.EditControl(Name=self._lang('搜索'))                # 开动化聊天栏,以C开首        self.C_MsgList = self.ChatBox.ListControl(Name=self._lang('音问'))                self.nickname = self.A_MyIcon.Name        print(f'开动化生效,赢得到已登录窗口:{self.nickname}')        def _checkversion(self):        self.HWND = FindWindow(classname='WeChatMainWndForPC')        wxpath = GetPathByHwnd(self.HWND)        wxversion = GetVersionByPath(wxpath)        if wxversion != self.VERSION:            Warnings.lightred(self._lang('版块不一致,需要3.9.8.15版块微信,前去下载:https://github.com/tom-snow/wechat-windows-versions/releases?page=2', 'WARNING').format(wxversion, self.VERSION), stacklevel=2)            return False        def _show(self):        self.HWND = FindWindow(classname='WeChatMainWndForPC')        win32gui.ShowWindow(self.HWND, 1)        win32gui.SetWindowPos(self.HWND, -1, 0, 0, 0, 0, 3)        win32gui.SetWindowPos(self.HWND, -2, 0, 0, 0, 0, 3)        self.UiaAPI.SwitchToThisWindow()        def GetSessionAmont(self, SessionItem):        '''赢得聊天对象名和新音问条数                Args:            SessionItem (uiautomation.ListItemControl): 聊天对象控件                    Returns:            sessionname (str): 聊天对象名            amount (int): 新音问条数        '''        matchobj = re.search('\d+条新音问', SessionItem.Name)        amount = 0        if matchobj:            try:                amount = int([i for i in SessionItem.GetChildren()[0].GetChildren() if type(i) == uia.uiautomation.TextControl][0].Name)            except:                pass        if amount:            sessionname = SessionItem.Name.replace(f'{amount}条新音问','')        else:            sessionname = SessionItem.Name        return sessionname, amount        def CheckNewMessage(self):        '''是否有新音问'''        self._show()        return IsRedPixel(self.A_ChatIcon)    #self.A_ChatIcon 图像中的红色像素点来判断是否有新音问。在好多应用中,新音问未读时图标会深化为红色,因此通过检测图方向红色像素是否存在,不错障碍地笃定是否有新音问。        def GetNextNewMessage(self, savepic=False):        '''赢得下一个新音问'''        msgs_ = self.GetAllMessage()        if self.lastmsgid is not None and self.lastmsgid in [i[-1] for i in msgs_[:-1]]:            print('赢顺应前窗口新音问')            idx = [i[-1] for i in msgs_].index(self.lastmsgid)            MsgItems = self.C_MsgList.GetChildren()[idx+1:]            msgs = self._getmsgs(MsgItems, savepic)            return {self.CurrentChat(): msgs}         elif self.CheckNewMessage():            print('赢得其他窗口新音问')            while True:                self.A_ChatIcon.DoubleClick(simulateMove=False)                sessiondict = self.GetSessionList(newmessage=True)                if sessiondict:                    break            for session in sessiondict:                self.ChatWith(session)                MsgItems = self.C_MsgList.GetChildren()[-sessiondict[session]:]                msgs = self._getmsgs(MsgItems, savepic)                self.lastmsgid = msgs[-1][-1]                return {session:msgs}        else:            # print('莫得新音问')            return None                #该函数用于赢得下一个新音问。当先,它会尝试赢顺应前窗口的新音问,如若生效,则复返现时聊天窗口的音问列表。        #如若现时窗口莫得新音问,它会检验是否有其他窗口有新音问。如若有,则会逐一丝击聊天图标,开放有新音问的聊天窗口,并复返该窗口的音问列表。        #函数复返一个字典,包含每个聊天窗口的音问列表。如若莫得新音问,则复返None。                def GetAllNewMessage(self):        '''赢得扫数新音问'''        newmessages = {}        while True:            if self.CheckNewMessage():                self.A_ChatIcon.DoubleClick(simulateMove=False)                sessiondict = self.GetSessionList(newmessage=True)                for session in sessiondict:                    self.ChatWith(session)                    newmessages[session] = self.GetAllMessage()[-sessiondict[session]:]            else:                break        self.ChatWith(self._lang('文献传输助手'))        return newmessages        def GetSessionList(self, reset=False, newmessage=False):        '''赢顺应前聊天列表中的扫数聊天对象                Args:            reset (bool): 是否重置SessionItemList            newmessage (bool): 是否只赢得有新音问的聊天对象                    Returns:            SessionList (dict): 聊天对象列表,键为聊天对象名,值为新音问条数        '''        self.SessionItem = self.SessionBox.ListItemControl()        if reset:            self.SessionItemList = []        SessionList = {}        for i in range(100):            if self.SessionItem.BoundingRectangle.width() != 0:                try:                    name, amount = self.GetSessionAmont(self.SessionItem)                except:                    break                if name not in self.SessionItemList:                    self.SessionItemList.append(name)                if name not in SessionList:                    SessionList[name] = amount            self.SessionItem = self.SessionItem.GetNextSiblingControl()            if not self.SessionItem:                break                    if newmessage:            return {i:SessionList[i] for i in SessionList if SessionList[i] > 0}        return SessionList        def ChatWith(self, who, notfound: Literal['raise', 'ignore']='ignore'):        '''开放某个聊天框                Args:            who ( str ): 要开放的聊天框好友名;  * 最佳竣工匹配,不完全匹配只会考中搜索框第一个            notfound ( str, optional ): 未找到时的处理面容,可选:raise-抛出异常  ignore-忽略,默许ignore                    Returns:            chatname ( str ): 匹配值第一个的竣工名字        '''        self._show()        sessiondict = self.GetSessionList(True)        if who in list(sessiondict.keys())[:-1]:            if sessiondict[who] > 0:                who1 = f'{who}{sessiondict[who]}条新音问'            else:                who1 = who            self.SessionBox.ListItemControl(Name=who1).Click(simulateMove=False)            return who        self.UiaAPI.SendKeys('{Ctrl}f', waitTime=1)        self.B_Search.SendKeys(who, waitTime=1.5)        SearchResut = self.SessionBox.GetChildren()[1].GetChildren()[1]        firstresult = [i for i in SearchResut.GetChildren()[0].GetChildren() if who in i.Name][0]        if firstresult.Name == f'搜索 {who}':            if len(self.SessionBox.GetChildren()[1].GetChildren()) > 1:                self.B_Search.SendKeys('{Esc}')            if notfound == 'raise':                raise TargetNotFoundError(f'未查询到目标:{who}')            elif notfound == 'ignore':                return None        chatname = firstresult.Name        firstresult.Click(simulateMove=False)        return chatname        def SendMsg(self, msg, who=None, clear=True):        '''发送文本音问        Args:            msg (str): 要发送的文本音问            who (str): 要发送给谁,如若为None,则发送到现时聊天页面。*最佳竣工匹配,优先使用备注            clear (bool, optional): 是否排除本来的实质,        '''        if who in self.listen:            chat = self.listen[who]            chat.SendMsg(msg)            return None        if not msg:            return None        if who:            try:                editbox = self.ChatBox.EditControl(searchDepth=10)                if who in self.CurrentChat() and who in editbox.Name:                    pass                else:                    self.ChatWith(who)                    editbox = self.ChatBox.EditControl(Name=who, searchDepth=10)            except:                self.ChatWith(who)                editbox = self.ChatBox.EditControl(Name=who, searchDepth=10)        else:            editbox = self.ChatBox.EditControl(searchDepth=10)        if clear:            editbox.SendKeys('{Ctrl}a', waitTime=0)        self._show()        if not editbox.HasKeyboardFocus:            editbox.Click(simulateMove=False)                t0 = time.time()        while True:            if time.time() - t0 > 10:                raise TimeoutError(f'发送音问超时 --> {editbox.Name} - {msg}')            SetClipboardText(msg)            editbox.SendKeys('{Ctrl}v')            if editbox.GetValuePattern().Value:                break        editbox.SendKeys('{Enter}')            def SendFiles(self, filepath, who=None):        '''向现时聊天窗口发送文献                Args:            filepath (str|list): 要复制文献的统共旅途              who (str): 要发送给谁,如若为None,则发送到现时聊天页面。*最佳竣工匹配,优先使用备注                    Returns:            bool: 是否生效发送文献        '''        if who in self.listen:            chat = self.listen[who]            chat.SendFiles(filepath)            return None        filelist = []        if isinstance(filepath, str):            if not os.path.exists(filepath):                Warnings.lightred(f'未找到文献:{filepath},无法生效发送', stacklevel=2)                return False            else:                filelist.append(os.path.realpath(filepath))        elif isinstance(filepath, (list, tuple, set)):            for i in filepath:                if os.path.exists(i):                    filelist.append(i)                else:                    Warnings.lightred(f'未找到文献:{i}', stacklevel=2)        else:            Warnings.lightred(f'filepath参数形状额外:{type(filepath)},应为str、list、tuple、set形状', stacklevel=2)            return False                if filelist:            self._show()            if who:                try:                    if who in self.CurrentChat() and who in self.ChatBox.EditControl(searchDepth=10).Name:                        pass                    else:                        self.ChatWith(who)                except:                    self.ChatWith(who)                editbox = self.ChatBox.EditControl(Name=who)            else:                editbox = self.ChatBox.EditControl()            editbox.SendKeys('{Ctrl}a', waitTime=0)            t0 = time.time()            while True:                if time.time() - t0 > 10:                    raise TimeoutError(f'发送文献超时 --> {filelist}')                SetClipboardFiles(filelist)                time.sleep(0.2)                editbox.SendKeys('{Ctrl}v')                if editbox.GetValuePattern().Value:                    break            editbox.SendKeys('{Enter}')            return True        else:            Warnings.lightred('扫数文献齐无法生效发送', stacklevel=2)            return False                def GetAllMessage(self, savepic=False, n=0):        '''赢顺应前窗口中加载的扫数聊天纪录                Args:            savepic (bool): 是否自动保存聊天图片                    Returns:            list: 聊天纪录信息        '''        MsgItems = self.C_MsgList.GetChildren()        msgs = self._getmsgs(MsgItems, savepic)        return msgs        def LoadMoreMessage(self):        '''加载现时聊天页面更多聊天信息                Returns:            bool: 是否生效加载更多聊天信息        '''        loadmore = self.C_MsgList.GetChildren()[0]        loadmore_top = loadmore.BoundingRectangle.top        top = self.C_MsgList.BoundingRectangle.top        while True:            if loadmore.BoundingRectangle.top > top or loadmore.Name == '':                isload = True                break            else:                self.C_MsgList.WheelUp(wheelTimes=10, waitTime=0.1)                if loadmore.BoundingRectangle.top == loadmore_top:                    isload = False                    break                else:                    loadmore_top = loadmore.BoundingRectangle.top        self.C_MsgList.WheelUp(wheelTimes=1, waitTime=0.1)        return isload        def CurrentChat(self):        '''赢顺应前聊天对象名'''        uia.SetGlobalSearchTimeout(1)        try:            currentname = self.ChatBox.TextControl(searchDepth=15).Name            return currentname        except:            return None        finally:            uia.SetGlobalSearchTimeout(10)     def GetNewFriends(self):        '''赢得新的好友请求列表                Returns:            list: 新的好友请求列表,元素为NewFriendsElement对象,可平直调用Accept要领        Example:            >>> wx = WeChat()            >>> newfriends = wx.GetNewFriends()            >>> tags = ['标签1', '标签2']            >>> for friend in newfriends:            >>>     remark = f'备注{friend.name}'            >>>     friend.Accept(remark=remark, tags=tags)  # 汲取好友请求,并开采备注和标签        '''        self._show()        self.SwitchToContact()        self.SessionBox.ButtonControl(Name='ContactListItem').Click(simulateMove=False)        NewFriendsList = [NewFriendsElement(i, self) for i in self.ChatBox.ListControl(Name='新的一又友').GetChildren()]        AcceptableNewFriendsList = [i for i in NewFriendsList if i.acceptable]        print(f'赢得到 {len(AcceptableNewFriendsList)} 条新的好友请求')        return AcceptableNewFriendsList        def AddListenChat(self, who, savepic=False):        '''添加监听对象                Args:            who (str): 要监听的聊天对象名            savepic (bool, optional): 是否自动保存聊天图片,只针对该聊天对象灵验        '''        exists = uia.WindowControl(searchDepth=1, ClassName='ChatWnd', Name=who).Exists(maxSearchSeconds=0.1)        if not exists:            self.ChatWith(who)            self.SessionBox.ListItemControl(Name=who).DoubleClick(simulateMove=False)        self.listen[who] = ChatWnd(who, self.language)        self.listen[who].savepic = savepic     def GetListenMessage(self):        '''赢得监听对象的新音问'''        msgs = {}        for who in self.listen:            chat = self.listen[who]            chat._show()            msg = chat.GetNewMessage(savepic=chat.savepic)            # if [i for i in msg if i[0] != 'Self']:            if msg:                msgs[chat] = msg        return msgs     def SwitchToContact(self):        '''切换到通信录页面'''        self._show()        self.A_ContactsIcon.Click(simulateMove=False)     def SwitchToChat(self):        '''切换到聊天页面'''        self._show()        self.A_ChatIcon.Click(simulateMove=False)     def GetGroupMembers(self):        '''赢顺应前聊天群成员        Returns:            list: 现时聊天群成员列表        '''        ele = self.ChatBox.PaneControl(searchDepth=7, foundIndex=6).ButtonControl(Name='聊天信息')        try:            uia.SetGlobalSearchTimeout(1)            rect = ele.BoundingRectangle            Click(rect)        except:            return         finally:            uia.SetGlobalSearchTimeout(10)        roominfoWnd = self.UiaAPI.WindowControl(ClassName='SessionChatRoomDetailWnd', searchDepth=1)        more = roominfoWnd.ButtonControl(Name='检讨更多', searchDepth=8)        try:            uia.SetGlobalSearchTimeout(1)            rect = more.BoundingRectangle            Click(rect)        except:            pass        finally:            uia.SetGlobalSearchTimeout(10)        members = [i.Name for i in roominfoWnd.ListControl(Name='聊天成员').GetChildren()]        while members[-1] in ['添加', '移出']:            members = members[:-1]        roominfoWnd.SendKeys('{Esc}')        return members def GetAllFriendNicknames(self, keywords=None):    '''赢得扫数好友昵称列表    注:        1. 该要领运行技术取决于好友数目,约每秒6~8个好友的速率        2. 该要领未流程大宗测试,可能存在未知问题,如有问题请微信群内响应    Args:        keywords (str, optional): 搜索关键词,只复返包含关键词的好友昵称列表    Returns:        list: 扫数好友昵称列表    '''    self._show()    self.SwitchToContact()    self.SessionBox.ListControl(Name='有关东说念主').ButtonControl(Name='通信录照应').Click(simulateMove=False)    contactwnd = ContactWnd()    if keywords:        contactwnd.Search(keywords)    friends_nicknames = contactwnd.GetAllFriendNicknames()    contactwnd.Close()    self.SwitchToChat()    return friends_nicknames

代码赏析以及完结旨趣

开动化:在类的开动化要领中,当先检验微信是否照旧运行,如若莫得运行,则尝试启动微信。赢得微信的窗口句柄,并开采微信窗口的大小和位置。

赢得会话列表:GetSessionList 要领用于赢顺应前聊天列表中的扫数聊天对象。它会遍历聊天列表,并复返每个聊天对象的称呼和新音问数目。

切换聊天对象:ChatWith 要领用于切换到指定的聊天对象。

发送音问:SendMsg 要领用于向现时聊天对象发送文本音问。它会将音问发送到现时聊天对象的裁剪框中,并发送回车键以发送音问。

发送文献:SendFiles 要领用于向现时聊天对象发送文献。

赢得聊天纪录:GetAllMessage 要领用于赢顺应前聊天对象的扫数聊天纪录。它会遍历聊天纪录列表,并复返每个聊天纪录的信息。赢顺应前聊天对象称呼:CurrentChat 要领用于赢顺应前聊天对象的称呼。

赢得新的好友请求列表:GetNewFriends 要领用于赢得新的好友请求列表。它会遍历新的好友请求列表,并复返每个好友请求的信息。

添加监听对象:AddListenChat 要领用于添加监听对象。它会创建一个新的 ChatWnd 对象,并将其添加到监听对象字典中。

赢得监听对象的新音问:GetListenMessage 要领用于赢得监听对象的新音问。它会遍历监听对象字典,并赢得每个监听对象的新音问。

切换到通信录页面:SwitchToContact 要领用于切换到通信录页面。切换到聊天页面:SwitchToChat 要领用于切换到聊天页面。

赢顺应前聊天群成员:GetGroupMembers 要领用于赢顺应前聊天群的成员列表。它会遍历聊天群成员列表,并复返每个成员的称呼。

赢得扫数好友昵称列表:GetAllFriendNicknames 要领用于赢得扫数好友的昵称列表。它会打灵通信录窗口,并搜索指定的关键词(如若提供了关键词)。然后,它会遍历通信录列表,并复返每个好友的昵称。临了,它会关闭通信录窗口,并切换回聊天页面。

————————————————【SXVD-016】女教師の秘蜜 佐藤あい

本站仅提供存储做事,扫数实质均由用户发布,如发现存害或侵权实质,请点击举报。