Python

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 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() 函數中指定 xy 座標參數,這樣的效果就等於先呼叫 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('比對失敗')

參考資料

Share
Published by
Office Guide

Recent Posts

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

10 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

11 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

11 個月 ago

Linux 以 Cryptsetup 與 LUKS 加密磁碟教學與範例

介紹如何使用 Cryptset...

11 個月 ago