PyAutoGUI使用入門

Apostle浩發表於2024-05-20

PyAutoGUI 是一個 Python 模組,用於在圖形使用者介面 (GUI) 自動化中生成滑鼠和鍵盤輸入。它可以用於自動化任務、測試、模擬使用者輸入等。

安裝 PyAutoGUI

你可以使用 pip 安裝 PyAutoGUI:

pip install pyautogui

使用

import pyautogui    # 匯入模組

獲取螢幕大小

screenWidth, screenHeight = pyautogui.size()
screenWidth, screenHeight
(2560, 1600)

滑鼠功能

獲取滑鼠位置

currentMouseX, currentMouseY = pyautogui.position() # 獲取當前滑鼠位置
print(currentMouseX, currentMouseY)

移動滑鼠到指定位置

pyautogui.moveTo(100, 150)

滑鼠點選

# pyautogui.click()
# 先移動到指定位置再點選滑鼠
pyautogui.click(x=818, y=1568, clicks=2, interval=2, button="LEFT", duration=3)
# 其他點選操作
pyautogui.mouseDown()   # 按下滑鼠按鍵(預設左鍵)
pyautogui.mouseUp()     # 釋放滑鼠按鍵(預設左鍵)

引數說明:
x:X軸座標,預設為 None,即當前X軸座標

y:Y軸座標,預設為 None,即當前Y軸座標(注:X,Y 軸的座標只能同時指定,不能只指定某一個)

clicks:滑鼠的點選次數,預設為 1 次

intervalint 或浮點數,表示每次單擊之間需要等待多少秒,預設值為0.0,表示單擊之間沒有暫停

button:可選 LEFTMIDDLERIGHTPRIMARY(左鍵)或 SECONDARY(右鍵)。它的預設值是 PRIMARY

duration:如果指定了 X,Y 的值,並且該座標不是滑鼠當前位置的話,那麼 duration 引數就可以生效,它表示移動到指定座標花費的時間,預設為 0,表示立即移動。

找到螢幕上的指定圖片再點選

pyautogui.click("1.png") # 注意找不到圖片會丟擲錯誤

移動相對位置

pyautogui.move(400, 0) # 從當前位置往右移動400畫素

雙擊滑鼠

pyautogui.doubleClick(818, 1568)

滑鼠拖動

pyautogui.dragTo(x=None, y=None, duration=0.0, button="LEFT")     # 將滑鼠拖動到指定位置
pyautogui.drag(xOffset=0, yOffset=0, duration=0.0, button="PRIMARY")    # 將滑鼠拖動到螢幕上相對於當前位置的一個點。

主要引數:

x,y/xOffsetyOffsetxy 指明滑鼠事件發生的位置。如果為 None,則使用滑鼠當前位置。如果是浮點值,則將其舍入。如果在螢幕邊界之外,則事件發生在螢幕邊緣。

duration:如果指定了 XY 的值,並且該座標不是滑鼠當前位置的話,那麼 duration 引數就可以生效,它表示移動到指定座標花費的時間,預設為 0,表示立即移動。

button:可選 LEFTMIDDLERIGHTPRIMARY(左鍵)或 SECONDARY(右鍵)。它的預設值是 PRIMARY

滑鼠滾動

垂直滾動,在不同平臺滾動的效果可能不一樣。

# pyautogui.scroll(100)   # 向上滾動100
# pyautogui.scroll(-100)  # 向下滾動100
pyautogui.scroll(-5000, x=300, y=500)  # 移動到300, 500, 然後執行滾動

水平滾動,(適用與 OS X 和 Linux 平臺上)。

pyautogui.hscroll(100)   # 向右滾動100
pyautogui.hscroll(-100)   # 向左滾動100

螢幕功能

截圖功能

使用 screenshot() 函式來實現截圖功能。呼叫 screenshot() 將返回一個 Image 物件。傳入一個檔名字串將把截圖儲存到檔案中,並將其作為一個 Image 物件返回。透過 region 關鍵字引數來捕獲指定區域,只需傳遞一個由 left, top, width, height 組成的元組(left,top為左上角座標)。

pyautogui.screenshot()
pyautogui.screenshot(r'test_fullscreen.png')  # 預設擷取全屏
pyautogui.screenshot(r'test_region.png', region=(300, 300, 500, 1000))  # 擷取指定區域

定位功能

如果不知道要點選的內容在螢幕上的確切座標,就不能呼叫 moveTo()click() 函式。但是,如果有按鈕的影像,如下面這個圖片,那就可以呼叫 locateOnScreen('圖片路徑') 函式來獲取座標。返回值是一個元組:(left, top, width, height)。這個元組可以傳遞給 center() 來獲得該區域中心的座標(X,Y)。如果在螢幕上找不到影像,locateOnScreen() 將引發 ImageNotFoundException 異常。

location = pyautogui.locateOnScreen('1.png')
pyautogui.center(location)

訊息框功能

PyAutoGUI 利用 PyMsgBox 中的訊息框函式提供了一種跨平臺的純 Python 方法來顯示 javascript 樣式的訊息框。

alert()函式

pyautogui.alert(text='text', title='title', button='alert!')

confirm()函式

顯示帶有多個按鈕的訊息框。按鈕的數量和文字可以自己設定。單擊按鈕返回該按鈕的文字。

pyautogui.confirm(text='text', title='title', buttons=['再考慮一下', '解除安裝'])

prompt()函式

顯示一個包含 確認,取消 按鈕和文字輸入欄的訊息框,使用者可以輸入指定內容。當點選確認按鈕後,返回輸入框中的值;若點選取消,則返回 None

pyautogui.prompt(text='text', title='title', default='請輸入文字資訊')

password()函式

顯示一個包含 確認,取消 按鈕和文字輸入欄的訊息框,輸入的字元顯示為"*"。如果點選確認則返回輸入的文字;如果單擊“取消”,則為 None 。

pyautogui.password(text='text', title='title', default='密碼', mask='*')

鍵盤控制功能

write()函式

write()函式將在傳入的字串中鍵入字元。若要在按下每個字元鍵之間新增延遲間隔,interval引數可以設定每個按鍵之間新增延遲。

pyautogui.write('Hello world!', interval=0.25)    # 每個字元間隔0.25秒

注意:pyautogui 並不支援輸入框自動聚焦,所有輸入之前先要點選輸入框位置。

press()函式

press() 函式執行的操作相當於滑鼠操作的 click(),它接收傳遞給它的字串。

pyautogui.press('num0', presses=1, interval=0.0)

keys:傳入的鍵盤字串
presses:操作按鍵次數,預設一次
interval:每次按鍵的間隔時間,預設0

keys 所有取值如下:

['\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+',
',', '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';'
, '<', '=', '>', '?', '@', '[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'
, 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~', 'accept', 'add', 'alt',
'altleft', 'altright', 'apps', 'backspace', 'browserback', 'browserfavorites',
'browserforward', 'browserhome', 'browserrefresh', 'browsersearch','browserstop'
,'capslock', 'clear', 'convert', 'ctrl', 'ctrlleft','ctrlright', 'decimal',
'del', 'delete', 'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute',
'f1', 'f10', 'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2'
, 'f20', 'f21', 'f22', 'f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9'
, 'final', 'fn', 'hanguel', 'hangul','hanja', 'help', 'home', 'insert', 'junja'
, 'kana', 'kanji', 'launchapp1', 'launchapp2', 'launchmail', 'launchmediaselect'
, 'left', 'modechange', 'multiply', 'nexttrack', 'nonconvert'
, 'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7'
, 'num8', 'num9', 'numlock', 'pagedown', 'pageup', 'pause', 'pgdn', 'pgup'
, 'playpause', 'prevtrack', 'print', 'printscreen', 'prntscrn', 'prtsc'
, 'prtscr', 'return', 'right', 'scrolllock', 'select', 'separator', 'shift'
, 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab', 'up'
, 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen'
, 'command', 'option', 'optionleft', 'optionright']

hotkey()函式

接收多個字串引數,順序按下,再按相反的順序釋放。

pyautogui.hotkey('ctrl', 'shift', 'esc')

# 相當於
pyautogui.keyDown('ctrl')    # 按下 ctrl 
pyautogui.keyDown('shift')    # 按下 shift
pyautogui.keyDown('esc')    # 按下 esc
pyautogui.keyUp('esc')    # 釋放 ctrl 
pyautogui.keyUp('shift')    # 釋放 shift
pyautogui.keyUp('ctrl') # 釋放 esc

PyAutoGUI圖片定位常用三種方式

loacteOnScreen()定義圖片整體位置

print(pyautogui.locateOnScreen('1.png'))
print(type(pyautogui.locateOnScreen('1.png')))

locateOnScreen定點陣圖片,會返回一個pyscreeze.Box(left,top,width,height),lefttop是圖片左上角的座標,width和height是圖片的寬和高。

center()

返回locateOnScreen獲取圖片整體位置的中心點

img = pyautogui.locateOnScreen('1.png')
Center = pyautogui.center(img)
print(Center)
print(type(Center))

center可以根據locateOnScreen定點陣圖片的位置,會返回一個pyscreeze.Point格式的圖片中心左邊點Point(x=test1,y=test2),可以透過Point().x 來獲取Pointx的值,也可以透過Point().y 來獲取Pointy的值。

locateCenterOnScreen()定點陣圖片的中心點

print(pyautogui.locateCenterOnScreen('1.png'))
print(type(pyautogui.locateCenterOnScreen('1.png')))

locateCenterOnScreen()相當於是locateOnScreen()center()的結合。 返回值也和center()的返回值一樣。

影像定位不穩定解決方案

方案介紹

  • 模糊定位:藉助opencv的來提高識別率,在local函式中加入confidence引數,也就是識別準確度,當confidence越小時,定位的精度就會越低,從而實現模糊定位。

  • 灰度匹配:在local函式中加入grayscale引數,當grayscale=True時會使影像和螢幕截圖中的顏色去飽和,可以解決由於顯示器飽和度不同從而引起的顏色細微差異因而導致的影像定位失敗問題。

  • 指定範圍:在local函式中加入region引數,可以控制找圖範圍,從而提高找圖效率。

  • 多圖定位:icon在不同場景下可能有不同的顯示效果,可以把不同顯示效果的多張圖片歸為一個事件,對多張圖進行迴圈查詢,定位一張圖就可以對整個事件進行定位。

模糊查詢

opencv的安裝命令:

pip install opencv-python

pyautogui.locateOnScreen()函式中加入confidence引數,當confidence的值決定精度

t = pyautogui.locateOnScreen('1.png', confidence=0.8)
print(pyautogui.center(t))
Point(x=200, y=913)

灰度匹配

pyautogui.locateOnScreen()函式中加入grayscale=True,就可以實現灰度匹配

t = pyautogui.locateOnScreen('1.png', grayscale=True)
print(pyautogui.center(t))

指定範圍

local函式中加入region引數,可以控制找圖範圍,從而提高找圖效率。

region(x,y,width,height),其中x,y為範圍左上角座標,width,height為範圍的寬和高。

t = pyautogui.locateOnScreen('1.png', grayscale=True, region=(100, 900, 300, 1000))
print(pyautogui.center(t))

多圖定位

可以對一個icon截多張不同的圖,每一張圖都代表這個icon,只要定位其中一張圖就能定位這個icon

locateOnScreent()函式進行二次封裝,多張圖片之間用 | 間隔,實現迴圈找圖。

from pyautogui import *
 
#把字串按'|'切割
def word_cut(args):
    tup = []
    if '|' in args:
        re1 = args.split('|')
        return re1
    else:
        tup.append(args)
        return tuple(tup)
 
#判斷影像是否找到,如果找到就返回True,沒找到就跳過
def assertPIC(args):
    if locateOnScreen(args) == None:
        pass
    else:
        return True
 
#迴圈找圖,找到就返回影像中心點,沒找到就列印'沒找到'
def img_locat(args):
    arg = word_cut(args)
    for i in range(len(arg)):
        if assertPIC(arg[i]):
            return center(locateOnScreen(arg[i]))
        else:
            print('沒找到')
 
#測試
print(img_locat('1.png'))
Point(x=200, y=914)