python win32gui+pynput 自动回复qq消息

寒假期间,因为疫情,这几天班群要天天报平安,早上起不来就写了这个。(如果身体有异常记得改哦,不能谎报)

先谢谢以下博主:

https://www.cnblogs.com/hwj2019/p/11552055.html

https://www.jb51.net/article/155520.htm

https://blog.csdn.net/u011311291/article/details/80016859

https://www.jianshu.com/p/b77d934cc252

当然还有一些博主,这里就列了主要一部分。

 

使用条件:

        已安装python3.+,再安装pywin32(https://www.cnblogs.com/Swalllow/p/11711750.html 我是照这个博客安装成功的),最后安装pynout(pip install pynput  即可)。

使用限制:

        window系统,qq对话窗口只能单独打开,而且必须打开,这样窗口名才会和群名称或对话的用户昵称一致。

使用原理:

        譬如和一个叫“大兄弟”的朋友对话,先用win32gui 打开“大兄弟”聊天窗口,并使其加入到线程顶置该窗口,再设置其窗口大小和位置。然后鼠标拖动(我拖动的区域是固定的,会不会鼠标左键双击一个固定位置会更好呢?这样就不受消息长短的限制了,可以改一下试试),ctrl+c 复制获取最新一条消息内容到剪切板,然后从剪切板上拿到该消息:字符串data,再用re正则表达式抽取你要的信息,再写一个逻辑你要回复的内容data,再用win32gui 打开“大兄弟”聊天窗口,并使其加入到线程顶置该窗口,ctrl+v粘贴上去,然后ctrl+enter发送。

功能特点:

        用了sched实现了一个时间调度程序,不像time.sleep一样阻塞进程。可以定一个时间:上午九点,那么上午九点每隔一分钟就会执行上述代码一次,一共二十次,只要一次成功回复后,之后的几次定时会继续,但到了时间也不会执行了。

配合闹钟使用:

        比如你想在9:00到9:20这个时间段检测21次,那么你可以定一个9:21的闹钟(window自带的闹钟即可),如果它回复成功了会把你的系统音量调至最低,那么闹钟就相当于没有开启了。反之音量会最高。

上代码:

import win32gui,win32api

import win32con
import win32clipboard as win32clip
import re
from pynput.keyboard import Key
from pynput.keyboard import Controller as Controller_k
from pynput.mouse import Button, Controller
import time, sched
import datetime


s = sched.scheduler(time.time, time.sleep)

mouse = Controller()

keyboard = Controller_k()

WM_APPCOMMAND = 0x319

APPCOMMAND_VOLUME_MAX = 0x0a
APPCOMMAND_VOLUME_MIN = 0x09

class sendMsg():
    def get_clip(self):
        #获取剪切板内容
        try:
            win32clip.OpenClipboard()
            data = win32clip.GetClipboardData()
            win32clip.CloseClipboard()
            return data
        except:
            return 'null'

    def getmsg(self):
        #拖动鼠标
        mouse.position = (395, 470)
        mouse.press(Button.left)
        time.sleep(0.1)
        mouse.release(Button.left)

        mouse.position = (395, 470)
        mouse.press(Button.left)
        mouse.move(90, 85)
        time.sleep(0.5)
        mouse.release(Button.left)
        with keyboard.pressed(Key.ctrl):  # 按下ctrl+c
            keyboard.press('c')
            time.sleep(0.5)
            keyboard.release('c')

    def __init__(self,receiver):
        self.receiver=receiver
        #初始化剪切板为:hello world ,我之前用这段代码可以,不知现在为何没效果
        win32clip.OpenClipboard()
        win32clip.EmptyClipboard()
        win32clip.SetClipboardData(win32con.CF_UNICODETEXT, 'hello world!')
        win32clip.CloseClipboard()


    def solve(self):
        self.getmsg()
        data=self.get_clip()
        print('get',data)
        data=data.lstrip()
        try:
            #按自己所需的匹配,我这里的格式比如:23 1234567890大兄弟正常
            data=re.findall('(\d*?)\s+?\d{10}.*?',data)
            data=int(data[0])
            data+=1
            data=str(data)
            data+=u' 学号 姓名' # 学号 姓名
        except:
            data=''
        return data

    def wakeup(self):

        mouse.position = (1, 1)
        mouse.press(Button.left)
        time.sleep(0.1)
        mouse.release(Button.left)

    #发送消息
    def sendmsg(self):
        #找到该窗口
        qq=win32gui.FindWindow(None,self.receiver)
        print(qq)  

        #窗口激活顶置改大小
        win32gui.SendMessage(qq, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
        win32api.keybd_event(13, 0, 0, 0)

        win32gui.SendMessage(qq, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
        win32gui.SetForegroundWindow(qq)
        win32gui.SetWindowPos(qq, win32con.HWND_TOPMOST, 344, 100, 679, 568, win32con.SWP_SHOWWINDOW)
        # print(win32gui.GetWindowRect(qq)) #
        # (344, 100, 1023, 668)


        time.sleep(1)
        time.sleep(0.5)


        data=self.solve()
        win32gui.SendMessage(qq, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
        win32api.keybd_event(13, 0, 0, 0)
        win32gui.SendMessage(qq, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
        win32gui.SetForegroundWindow(qq)

        keyboard.type(data)  #写下发送内容data

        with keyboard.pressed(Key.ctrl):  # 按下ctrl+enter 发送
            keyboard.press(Key.enter)
            keyboard.release(Key.enter)
        if len(data) >=6:
            return True
        return False


flag=False

def adjust_voice(flag=True):
    if flag:
        # 音量最大
        win32api.SendMessage(-1, WM_APPCOMMAND, 0x30292, APPCOMMAND_VOLUME_MAX * 0x10000)
    else:
        # 音量最小
        win32api.SendMessage(-1, WM_APPCOMMAND, 0x30292, APPCOMMAND_VOLUME_MIN * 0x10000)

def go():
    print(datetime.datetime.now())
    global flag
    if flag==False:
        receiver= '大兄弟' #d对话的群名称或人的昵称
        qq = sendMsg(receiver)
        flag=qq.sendmsg()
        if flag:
            adjust_voice(False)
        print(flag)


def test_time():
    now_time = datetime.datetime.now()
    #这个minutes=+1 没什么用,如果要设置第二天回复的话改成days+1
    next_time = now_time + datetime.timedelta(minutes=+1)
    next_year = next_time.date().year
    next_month = next_time.date().month
    next_day = next_time.date().day
    # 时间是9点 
    next_time = datetime.datetime.strptime(str(next_year) + "-" + str(next_month)
                                           + "-" + str(next_day) +
                                           " 09:00:00",
                                           "%Y-%m-%d %H:%M:%S")
    timer_start_time = (next_time - now_time).total_seconds()
    print(timer_start_time,next_time)
    i=0
    #s.enter(timer_start_time-30, 2, adjust_voice,argument=(True,))
    #每隔1分钟一个,加20个
    while i<=20:
        s.enter(timer_start_time, 1, go)
        i+=1
        timer_start_time+=60

    s.run()

if __name__ == '__main__':
    test_time()
    #直接go() 方便提前测试
    # go()



 

你可能感兴趣的:(python)