| by 鲍 建伟 | No comments

PyAutoGUI简单研究和应用(2)

接上文,今天继续做。

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

pyautogui.FAILSAFE = True

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 move_mouse_to_location(x_coordinate, y_coordinate):
    pyautogui.moveTo(int(x_coordinate), int(y_coordinate))

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

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()
    while 1:
        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())))

在这里我暂时将循环写死,也就是说这个代码跑起来之后会一直不断的截图,那么问题来了,代码一直控制鼠标我压根没法操作啊,为了解决这个问题,下面这行代码来了:

pyautogui.FAILSAFE = True

这行代码意思就是:如果把鼠标光标在屏幕左上角,PyAutoGUI函数就会产生pyautogui.FailSafeException异常。当我们需要需要中断PyAutoGUI函数,就把鼠标光标在屏幕左上角即可。

上面所有的代码都是疯狂截图,但是疯狂截图没有用啊,我需要当我收到信息的时候才截图,所以经过思考之后,我觉得应该这样做:

1.设定两个全局变量,第一个存储上次截图的文件名,第二个存储上次截图文件的MD5值。
2.我设定的比较逻辑是这样,第一次截图时候不对比,第二次截图与上次截图的MD5值对比,如果相同就删掉。

新添加的全局变量和方法等:

global behind_filename
global behind_md5
behind_filename = None
behind_md5 = None

def save_behind_filename(filename):
# 存储上次截图文件的文件名
    global behind_filename
    behind_filename = filename
    return behind_filename

def save_behind_hash(filename):
# 存储上次截图的文件MD5值
    global behind_md5
    behind_md5 = hash_calculate(filename)
    return

def hash_calculate(filename):
# 计算文件的MD5值
    with open(filename, 'rb') as f:
        md5_obj = hashlib.md5()
        md5_obj.update(f.read())
        hash_final = md5_obj.hexdigest()
    return str(hash_final).upper()

def del_file(filename):
# 删除文件
    os.remove(filename)

主函数:

    while 1:
        if behind_md5 and behind_filename:
            filename = 'screenshot-{}.jpg'.format(int(time.time()))
            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],
                       filename)
            new_hash = hash_calculate(filename)
            if new_hash == behind_md5:
                del_file(filename)
            else:
                save_behind_filename(filename)
                save_behind_hash(filename)
        else:
            filename = 'screenshot-{}.jpg'.format(int(time.time()))
            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],
                       filename)
            save_behind_filename(filename)
            save_behind_hash(filename)

做完了,可以做到收到新消息即可截图。下一步需要解决动画表情时候疯狂截图的问题,下一篇继续研究。

发表评论