简介
设计的初衷本来是来源于期末课程的作业,本来微信有很多可以用的库,例如:itchat,但是实际运用发现由于微信的限制,网页微信基本不可以使用了,所以几乎堵死了这些现成的库。但是我不甘心呀。
开发流程
一、问题分析
所面临的问题其实很明显,我们需要获取聊天时对方发来的消息,并把消息post给机器人API并得到回复,再将回复消息粘贴到聊天框,并发送。
由此,我们可以知道,需要剪贴板,需要模拟按键,需要post请求
所以我们使用以下包
import win32guiimport win32conimport win32clipboard as wimport timeimport win32apiimport requests
二、代码实现
1.得到对方发送来的消息
首先在这一步中我们需要拿到对方发来的消息,在win32中,为了方便定位复制位置,首先将聊天窗口独立打开,并全屏。
经过观察发现,新消息基本是出现在同一位置
此时我们已经可以确定将鼠标移动到的位置
下一步将确定如何选中文本
在观察后发现实际只需要右键就可以选中全部文本
但是虽然选中了但是会出现一个菜单,菜单中有复制选项。
最初的想法是移动鼠标左键点击复制,但是实际操作发现不现实,精度太低了,容易出错。
所以选择再左键点击下关闭菜单,然后使用模拟Ctrl+C的快捷键复制
win32api.SetCursorPos([90,680])#移动鼠标位置#执行右单键击win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)time.sleep(2)#延时#执行左单键击win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)time.sleep(2)# 以下为“CTRL+C”组合键,回车发送,(方法一)win32api.keybd_event(17, 0, 0, 0) # ctrl键位码是17win32api.keybd_event(67, 0, 0, 0) # v键位码是67win32api.keybd_event(67, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)
通过以上操作,已经成功获得了发送的文字
2.从剪贴板获取信息并发送
这一步很简单,直接使用代码表示
w.OpenClipboard() #打开剪贴板msg = w.GetClipboardData()#获取信息#关闭剪贴板w.CloseClipboard()
url = '/txapi/robot/index?key=xxxxx&question={}'.format(msg) #机器人API地址html = requests.get(url)returnmsg = html.json()["newslist"][0]['reply']#打开剪贴板w.OpenClipboard()#清空剪贴板w.EmptyClipboard()#设置剪贴板内容w.SetClipboardData(win32con.CF_UNICODETEXT, returnmsg)#获取剪贴板内容data = w.GetClipboardData()#关闭剪贴板w.CloseClipboard()
并将机器人的回复放到剪贴板中
3.发送消息
在这一部分,我们将发送消息,经过观察发现微信的信息框在获取信息结束后是失焦状态,所以我们需要移动鼠标并点击信息框,才可以输入信息。
在输入状态下,使用模拟Ctrl+V的按键操作,粘贴机器人的回复
并使用模拟回车,发送消息。
win32api.SetCursorPos([100,780]) #移动鼠标#执行左单键击,若需要双击则延时几毫秒再点击一次即可win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)# 以下为“CTRL+V”组合键,回车发送,(方法一)win32api.keybd_event(17, 0, 0, 0) # ctrl键位码是17win32api.keybd_event(86, 0, 0, 0) # v键位码是86win32api.keybd_event(86, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键win32api.keybd_event(17, 0, win32con.KEYEVENTF_KEYUP, 0)time.sleep(1) # 缓冲时间win32api.keybd_event(13, 0, 0, 0) # Rutrn键位码是13,按下win32api.keybd_event(13, 0, win32con.KEYEVENTF_KEYUP, 0) # 释放按键
4.补充
程序获取窗口句柄的代码
name = 'XXX'#聊天窗口的名字 handle = win32gui.FindWindow(None, name)
总结
本次项目完成,虽然基本完成了逻辑的实现,但是还是有很多问题存在,大体的设计思路如上,但是不代表最终程序,还有诸如:检测回复状态,重复执行实现等问题等待读者去解答。这也是为了调动积极性,始终复制代码不代表学会。
掘金地址:/post/7106861239560568846/