| by 鲍 建伟 | No comments

PyAutoGUI简单研究和应用(1)

1.什么是 PyAutoGUI

PyAutoGUI 是一个老外写的开源的跨平台(win,Linux,OS X)自动化工具,可以用代码控制键盘和鼠标进行操作,类似按键精灵(可能类似,我也没用过按键精灵)?

2.安装(windows)

pip install pyautogui

3.测试一下

import pyautogui
Width, Height = pyautogui.size() # 获取屏幕的长和宽(像素点)
pyautogui.moveTo(Width / 2, Height / 2)# 移动到坐标(屏幕中央的坐标)

以上代码是让鼠标移动到屏幕最中央。

4.实践

我为什么突然研究这个 PyAutoGUI 库,是我有个想法,我想做一个自动获取微信撤回的消息,也就是微信防撤回,但是吧,网上的代码我不信任,因为他们基本都是使用了 itchat 这个库,需要我扫码登录,我很不信任这种操作。所以,我准备用以下思路操作(只针对文字和图片):

1.获取自己的电脑版微信屏幕坐标
2.模拟双击,即可弹出微信界面
3.获取聊天图标的坐标,模拟双击
4.微信的机制是,双击聊天图标,如果有人给你发消息了,微信会直接定位到这个人的聊天框,定位到微信界面第一聊天框,后面仔细讲。
5.模拟单击聊天框
6.截图
7.和本地文件比对,如果哈希值一样就不存了

1.获取自己的电脑版微信屏幕坐标

这有个取巧的方法,使用微信的截图快捷键Alt+A,自动显示坐标,如下图:

第一行就是详细坐标,同理,可以获取到聊天图标和第一行聊天记录的坐标了
聊天按钮

代码如下:

# 默认值都是我自己的位置坐标
def get_wechat_coordinate():
    x_coordinate = input('输入微信在任务栏的x坐标:')
    y_coordinate = input('输入微信在任务栏的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 1677, 1058

def get_chat_coordinate():
    x_coordinate = input('输入微信聊天的x坐标:')
    y_coordinate = input('输入微信聊天的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 564, 321

def get_first_chat_coordinate():
    x_coordinate = input('输入微信第一行聊天的x坐标:')
    y_coordinate = input('输入微信第一行聊天的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 687, 321

def get_final_chat_coordinate():
# 最终截图时用
    x_coordinate = input('输入微信聊天框右下角的x坐标:')
    y_coordinate = input('输入微信聊天框右下角的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 687, 321

def get_start_chat_coordinate():
    x_coordinate = input('输入微信聊天框左上角的x坐标:')
    y_coordinate = input('输入微信聊天框左上角的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 1384, 813

2.模拟双击和单击

def clict_twice():# 双击
    pyautogui.click(clicks=2)

def clict_once(): # 单击
    pyautogui.click(clicks=1)

3.移动鼠标到指定坐标

def move_mouse_to_location(x_coordinate, y_coordinate):
    pyautogui.moveTo(int(x_coordinate), int(y_coordinate))

4.截图

def screenshot(start_x, start_y, finish_x, finish_y, filename):
    hwnd = 0
    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()
    saveBitMap = win32ui.CreateBitmap()
    saveBitMap.CreateCompatibleBitmap(mfcDC, finish_x, finish_y)
    saveDC.SelectObject(saveBitMap)
    saveDC.BitBlt((0, 0), (finish_x, finish_y), mfcDC, (start_x, start_y), win32con.SRCCOPY)
    saveBitMap.SaveBitmapFile(saveDC, filename)

这里截图我用了windows的API,速度很快。

5.最终代码:

import pyautogui
import time
import win32gui, win32ui, win32con, win32api

# 获取坐标操作
def get_wechat_coordinate():
    x_coordinate = input('输入微信在任务栏的x坐标:')
    y_coordinate = input('输入微信在任务栏的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 1677, 1058

def get_chat_coordinate():
    x_coordinate = input('输入微信聊天的x坐标:')
    y_coordinate = input('输入微信聊天的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 564, 321

def get_first_chat_coordinate():
    x_coordinate = input('输入微信第一行聊天的x坐标:')
    y_coordinate = input('输入微信第一行聊天的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 687, 321

def get_final_chat_coordinate():
    x_coordinate = input('输入微信聊天框右下角的x坐标:')
    y_coordinate = input('输入微信聊天框右下角的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 1384, 813

def get_start_chat_coordinate():
    x_coordinate = input('输入微信聊天框左上角的x坐标:')
    y_coordinate = input('输入微信聊天框左上角的y坐标:')
    if x_coordinate and y_coordinate:
        return x_coordinate, y_coordinate
    else:
        return 536, 226
# 获取结束
# 鼠标操作方法
def clict_once():
    pyautogui.click(clicks=1)

def clict_twice():
    pyautogui.click(clicks=2)

def move_mouse_to_location(x_coordinate, y_coordinate):
    pyautogui.moveTo(int(x_coordinate), int(y_coordinate))
# 鼠标操作方法结束
# 截图方法
def screenshot(start_x, start_y, finish_x, finish_y, filename):
    hwnd = 0
    hwndDC = win32gui.GetWindowDC(hwnd)
    mfcDC = win32ui.CreateDCFromHandle(hwndDC)
    saveDC = mfcDC.CreateCompatibleDC()
    saveBitMap = win32ui.CreateBitmap()
    saveBitMap.CreateCompatibleBitmap(mfcDC, finish_x, finish_y)
    saveDC.SelectObject(saveBitMap)
    saveDC.BitBlt((0, 0), (finish_x, finish_y), mfcDC, (start_x, start_y), win32con.SRCCOPY)
    saveBitMap.SaveBitmapFile(saveDC, filename)

if __name__ == '__main__':
    # 获取坐标
    wechat_coordinate = get_wechat_coordinate()
    chat_coordinate = get_chat_coordinate()
    first_chat_coordinate = get_first_chat_coordinate()
    start_chat_coordinate = get_start_chat_coordinate()
    final_chat_coordinate = get_final_chat_coordinate()
    # 开始操作鼠标
    move_mouse_to_location(wechat_coordinate[0], wechat_coordinate[1])
    clict_twice()
    move_mouse_to_location(chat_coordinate[0], chat_coordinate[1])
    clict_twice()
    move_mouse_to_location(first_chat_coordinate[0], first_chat_coordinate[1])
    clict_once()
    # 保存截图
    screenshot(start_chat_coordinate[0], start_chat_coordinate[1], final_chat_coordinate[0] - start_chat_coordinate[0],
               final_chat_coordinate[1] - start_chat_coordinate[1], 'screenshot-{}.jpg'.format(int(time.time())))

以上就是第一部分,基本完成,下一步思路是这样,写个死循环,每秒截图四次,同时进行截图的MD5值对比,只有对比不同时候才保存。待续,明天再写。

发表评论