本篇介紹如何在 Python 程式中使用 PyAutoGUI 模組來自動操作滑鼠與鍵盤,將原本人工的操作改以程式來自動執行。
PyAutoGUI 是一套可以控制電腦滑鼠與鍵盤的 Python 模組,適合用來將重複性的人工滑鼠或鍵盤操作自動化,甚至可以用於撰寫簡單的遊戲外掛程式。
PyAutoGUI 支援各種的滑鼠操作,例如滑鼠的移動、拖曳、點擊等。
螢幕上的位置可以透過 X 與 Y 座標的方式來定義,座標的原點 (0, 0)
位於螢幕的左上角,X 軸往右遞增,Y 軸則是往下遞增:
(0, 0) (1919, 0) +-------------------------------------+ | | | | | | | 1920 x 1080 | | | | | | | +-------------------------------------+ (1079, 0) (1919, 1079)
以 1920 x 1080
解析度的畫面來說,座標 (0, 0)
就代表螢幕上做左上角的像素,而最右下角的像素座標就是 (1919, 1079)
。
PyAutoGUI 的 size()
函數可以用來取得目前螢幕的解析度,而 position()
函數則可以取得滑鼠在螢幕上的座標:
import pyautogui # 取得螢幕解析度大小 size = pyautogui.size() print("{} x {}".format(size.width, size.height)) # 取得目前滑鼠位置 position = pyautogui.position() print("({}, {})".format(position.x, position.y))
1920 x 1080 (1384, 150)
若要檢查特定的座標是否位於螢幕中,可以使用 onScreen()
函數:
# 檢查座標是否位於螢幕中 if pyautogui.onScreen(1230, 560): print("座標位於螢幕中") else: print("座標位於螢幕之外")
若要將滑鼠移動到指定的位置,可以使用 moveTo()
函數,並指定目標點的座標:
# 將滑鼠移動到 (1230, 560) 座標位置上 pyautogui.moveTo(1230, 560)
如果希望只單純移動滑鼠的 X 座標或 Y 座標,可以將要固定的座標設定為 None
:
# 將滑鼠 X 座標移動到 1230,Y 座標保持不變 pyautogui.moveTo(1230, None) # 將滑鼠 Y 座標移動到 560,X 座標保持不變 pyautogui.moveTo(None, 560)
在預設的狀況下,PyAutoGUI 會將滑鼠立刻移動到指定的座標位置上,如果希望滑鼠以指定的速度慢慢移過去,可以在 moveTo()
的第三個參數設定移動花費的秒數:
# 以 2 秒的時間將滑鼠移動到 (1230, 560) 座標位置上 pyautogui.moveTo(1230, 560, 2)
如果希望滑鼠以目前座標為基準,移動至指定的相對位置上,可以使用 move()
函數:
# 以目前位置為基準,將滑鼠移動到 (-50, 100) 的相對位置上 pyautogui.move(-50, 100)
執行上面這行程式之後,滑鼠就會向左移動 50
像素,並向下移動 100
像素。
若要將滑鼠拖曳至指定的座標位置,可以使用 dragTo()
函數,用法與 moveTo()
類似,也可以指定花費的秒數:
# 將滑鼠以左鍵拖曳至 (860, 560) 座標位置上 pyautogui.dragTo(860, 560, button='left') # 以 2 秒的時間將滑鼠以左鍵拖曳至 (860, 560) 座標位置上 pyautogui.dragTo(860, 560, 2, button='left')
在呼叫 dragTo()
函數時可以使用 button
參數指定滑鼠在拖曳時要按下按鍵,可以使用的選項有 'left'
、'middle'
與 'right'
。
PyAutoGUI 在控制滑鼠移動時,若只有指定花費的時間,預設會以等速的方式移動,若希望滑鼠以比較複雜的方式移動,可以加上額外的 easing 參數來指定滑鼠移動的方式:
# 開始慢,後來快 pyautogui.moveTo(100, 100, 2, pyautogui.easeInQuad) # 開始快,後來慢 pyautogui.moveTo(100, 100, 2, pyautogui.easeOutQuad) # 前後快,中間慢 pyautogui.moveTo(100, 100, 2, pyautogui.easeInOutQuad) # 來回彈跳移動 pyautogui.moveTo(100, 100, 2, pyautogui.easeInBounce) # 來回彈跳移動 pyautogui.moveTo(100, 100, 2, pyautogui.easeInElastic)
若需要點擊滑鼠按鍵,可以使用 click()
函數:
# 點擊滑鼠左鍵
pyautogui.click()
click()
預設會點擊滑鼠左鍵,若要點擊其他按鍵,可以使用 button
參數指定按鍵,可以使用的選項有 'left'
、'middle'
與 'right'
:
# 點擊滑鼠右鍵 pyautogui.click(button='right')
通常滑鼠的點擊會配合指定的點擊位置,我們可以在 click()
函數中指定 x
與 y
座標參數,這樣的效果就等於先呼叫 moveTo()
移動到指定位置後再點擊滑鼠:
# 移動至 (100, 200) 後點擊滑鼠左鍵 pyautogui.click(x=100, y=200)
若要連續點擊多次滑鼠,可以使用 clicks
參數指定點擊次數,而 interval
參數可以指定點擊的間隔時間:
# 點擊兩次滑鼠左鍵 pyautogui.click(clicks=2) # 點擊兩次滑鼠左鍵,間隔 0.25 秒 pyautogui.click(clicks=2, interval=0.25) # 點擊三次滑鼠右鍵,間隔 0.25 秒 pyautogui.click(button='right', clicks=3, interval=0.25)
PyAutoGUI 有針對常用的滑鼠點擊動作,提供一些簡潔的函數,方便使用:
# 點擊兩次滑鼠左鍵 pyautogui.doubleClick() # 點擊三次滑鼠左鍵 pyautogui.tripleClick() # 點擊滑鼠右鍵 pyautogui.rightClick()
如果希望分開操作滑鼠的按下與放開動作,可以使用 mouseDown()
與 mouseUp()
函數:
# 按下滑鼠 pyautogui.mouseDown() # 放開滑鼠 pyautogui.mouseUp() # 按下滑鼠右鍵 pyautogui.mouseDown(button='right') # 將滑鼠移動至 (100, 200) 然後放開右鍵 pyautogui.mouseUp(button='right', x=100, y=200)
若要滾動滑鼠的滾輪,可以使用 scroll()
函數:
# 向上滾動 10 次 pyautogui.scroll(10) # 向下滾動 10 次 pyautogui.scroll(-10) # 將滑鼠移動至 (100, 100),然後向上滾動 10 次 pyautogui.scroll(10, x=100, y=100)
在 macOS 與 Linux 系統中,PyAutoGUI 也支援橫向的滾輪操作:
# 向右滾動 10 次 pyautogui.hscroll(10) # 向左滾動 10 次 pyautogui.hscroll(-10)
PyAutoGUI 的鍵盤操作主要是使用 write()
函數,它可以依序輸入指定的按鍵,而按鍵之間的間隔時間可以使用 interval
參數來指定:
# 立刻輸入字串 pyautogui.write('Hello world!') # 輸入字串,按鍵間隔 0.25 秒 pyautogui.write('Hello world!', interval=0.25)
若要輸入一些特殊的按鍵,可以使用 press()
函數,可用的按鍵定義在 pyautogui.KEYBOARD_KEYS
中:
# 按下 Enter 鍵 pyautogui.press('enter') # 按下 F1 鍵 pyautogui.press('f1') # 按下左方向鍵 pyautogui.press('left')
若要按住特定按鍵,可以使用 keyDown()
與 keyUp()
函數:
# 按住 Ctrl 鍵 pyautogui.keyDown('ctrl') # 輸入 v pyautogui.write('v') # 放開 Ctrl 鍵 pyautogui.keyUp('ctrl')
上面這樣的組合,就等於按下 Ctrl + v 的作用,對應到 Windows 的快速鍵就會觸發貼上的動作。
按住特定按鍵下的輸入也可以使用 hold()
函數來處理,上面輸入的 Ctrl + v 也可以用以下的寫法替代:
# 按住 Ctrl 鍵,再輸入 v 鍵 with pyautogui.hold('ctrl'): pyautogui.write('v')
若要按下多個按鍵,可以使用 list 方式指定多個按鍵,若是重複的按鍵,也可以使用 presses
參數指定輸入次數:
# 按下三次左方向鍵 pyautogui.press(['left', 'left', 'left']) # 按下三次左方向鍵 pyautogui.press('left', presses=3)
當需要組合多個按鍵同時按下時,可以使用 hotkey()
函數,它可以依序按住每一個按鍵,然後再按照相反的順序放開:
# 依序按住 Ctrl、Shift、Esc 按鍵,並反序放開 pyautogui.hotkey('ctrl', 'shift', 'esc')
上面這一行 hotkey()
的呼叫就等於以下六行:
# 依序按住 Ctrl、Shift、Esc 按鍵,並反序放開 pyautogui.keyDown('ctrl') pyautogui.keyDown('shift') pyautogui.keyDown('esc') pyautogui.keyUp('esc') pyautogui.keyUp('shift') pyautogui.keyUp('ctrl')
PyAutoGUI 除了可以操控滑鼠與鍵盤之外,它還可以將螢幕畫面儲存下來,以及從畫面中尋找特定的圖片位置(例如尋找特定的按紐位置等),這項功能對於自動化操作的程式設計非常有幫助。
若要將目前的螢幕畫面擷取下來,可以使用 screenshot()
函數:
# 擷取螢幕畫面 im1 = pyautogui.screenshot() # 擷取螢幕畫面,同時儲存至檔案 im2 = pyautogui.screenshot('my_screenshot.png')
若只想要擷取螢幕中的部分畫面,可以在呼叫 screenshot()
函數時,以 region
參數指定要擷取區域的左上角與右下角座標:
# 擷取螢幕部分畫面 im3 = pyautogui.screenshot(region=(0, 0, 300, 400))
使用 PyAutoGUI 操控滑鼠時,最常遇到的問題就是不知道目標在螢幕上的精確位置,這時候我們可以預先準備一張目標的圖片檔案,讓 PyAutoGUI 自動以圖片比對的方式,找出目標在螢幕上的位置,然後計算出精確的點擊座標位置。
舉例來說,假設我們希望 PyAutoGUI 自動點擊一個特別的按鈕,我們就可以準備一張按鈕的圖片 button.png
,然後使用 locateOnScreen()
找出該圖片位於螢幕中的座標位置:
# 取得指定圖片在螢幕上的位置 buttonLocation = pyautogui.locateOnScreen('button.png')
locateOnScreen()
所找出的結果會是一個方形區域(左上角與右下角座標),我們可以藉由 center()
計算出這個方形區域的中心點座標:
# 取得圖片的中心點座標
button7point = pyautogui.center(button7location)
btnX, btnY = button7point
有了中心點座標之後,就可以操控滑鼠進行點擊了:
# 以滑鼠點擊圖片中心點
pyautogui.click(btnX, btnY)
而以上的定位圖片、計算中心點、點擊的動作,也可以直接用下面這一行替代:
# 自動尋找圖片位置,計算中心點座標,並以滑鼠點擊 pyautogui.click('button.png')
locateCenterOnScreen()
可以直接取得指定圖片在螢幕上的位置中心座標,相當於結合 locateOnScreen()
與 center()
的效果:
# 取得指定圖片在螢幕上的位置中心 btnX, btnY = pyautogui.locateCenterOnScreen('button.png')
在 1920 x 1080 解析度的螢幕上尋找特定的圖片可能會花費一至兩秒鐘,這對於遊戲的操作來說速度不太夠,但是對於普通的應用程式而言還算可用。
有時候我們要找的目標可能不會完全跟我們所提供的圖片相同,有可能按鈕周圍有一些微小的差異,這時候就可以使用 confidence
參數來指定信心水準,信心水準越低,容許的差異就越高:
# 取得指定圖片在螢幕上的位置(信心水準 0.9) buttonLocation = pyautogui.locateOnScreen('button.png', confidence=0.9)
若要使用 confidence
參數,必須先安裝 Python 的 OpenCV 套件。
如果在螢幕中有多個目標,我們可以使用 locateAllOnScreen()
取得所有目標的位置:
# 取得指定圖片在螢幕上出現的所有位置 for pos in pyautogui.locateAllOnScreen('someButton.png') print(pos)
在呼叫定位函數時,也可以加上 grayscale=True
參數使用灰階模式來定位目標,這樣可以讓定位的速度提升 30% 左右,但缺點是會增加誤判機率:
# 以灰階模式取得指定圖片在螢幕上的位置 buttonLocation = pyautogui.locateOnScreen('button.png', grayscale=True)
我們可以透過 Pillow 影像的 getpixel()
函數取得指定位置的像素值:
# 擷取螢幕畫面 im = pyautogui.screenshot() # 取得指定像素值 pixel = im.getpixel((100, 200)) print(pixel)
(9, 43, 86)
而 PyAutoGUI 也可以使用 pixel()
函數直接從螢幕上取得指定位置的像素值:
# 從螢幕取得指定位置像素值 pixel = pyautogui.pixel(100, 200) print(pixel)
(9, 43, 86)
另一種方式是直接以 pixelMatchesColor()
函數進行螢幕的像素比對:
# 比對螢幕上指定位置的像素值 if pyautogui.pixelMatchesColor(100, 200, (9, 43, 86)): print('比對成功') else: print('比對失敗')
如果希望進行比對時有容許的誤差,可以使用 tolerance
參數指定容許的誤差值:
# 比對螢幕上指定位置的像素值(容許誤差為 10) if pyautogui.pixelMatchesColor(100, 200, (19, 53, 76), tolerance=10): print('比對成功') else: print('比對失敗')