自動化測試之桌面自動化(PyAutoGUI)


1、PyAutoGUI介紹

  • pyautogui是用來做GUI桌面應用自動化的Python包,功能類似於按鍵精靈:可以實現控制鼠標、鍵盤、消息框、截圖、定位功能
  • 官方文檔: https://pyautogui.readthedocs.io/en/latest/
  • pyautogui的特點:
    • 純python實現, 源碼清晰可見
    • 跨平台,支持linux、windows、mac
    • 操作簡單,會Python就行
    • 需要特別注意的是:pyautogui不支持中文輸入,但是可以配合pyperclip模塊進行復制粘貼

安裝:

# Windows安裝pyautogui
pip install pyautogui -i https://pypi.tuna.tsinghua.edu.cn/simple

# mac安裝pyautogui
pip install pyobjc-core
pip install pyobjc
pip install pyautogui

# Linux安裝pyautogui
#sudo apt-get install scrot python3-tk python3-dev
pip install python3-xlib
pip install pyautogui
View Code

2、鼠標操作

2.1、屏幕和鼠標的位置

屏幕上的位置由X和Y直角坐標表示。X坐標從左側的0開始,向右增加。與數學不同,Y坐標從頂部的0開始,向下增加。

+---------------------------+
|                           | Y increases
|                           |     |
|   1920 x 1080 screen      |     |
|                           |     V
|                           |
|                           |
+---------------------------+ 1919, 1079
  • 左上角的像素位於坐標0、0。如果屏幕的分辨率為1920 x 1080,則右下角的像素將為1919、1079(因為坐標始於0,而不是1)。
  • 屏幕分辨率大小由該size()函數作為兩個整數的元組返回。該position()函數返回鼠標光標的當前X和Y坐標。

  • 在Python交互模式下,運行如下代碼:

import os
import time
import pyautogui

print(pyautogui.size())  # 屏幕分辨率

try:
    while True:
        x, y = pyautogui.position()  # 返回鼠標的坐標
        # 打印當前鼠標位置坐標
        print(f'鼠標坐標:x={x}, y={y}')
        time.sleep(1)
# 捕獲異常 KeyboardInterrupt:用戶中斷執行(通常是輸入^C)
except KeyboardInterrupt:
    print('已退出')
View Code
  • 要檢查XY坐標是否在屏幕上,請將它們(作為兩個整數參數或帶有兩個整數的單個元組/列表參數)傳遞給onScreen()函數,True如果它們在屏幕邊界之內,則返回該函數False
>>> pyautogui.onScreen(0, 0)
True
>>> pyautogui.onScreen(0, -1)
False

2.2、鼠標移動

moveTo()函數會將鼠標光標移至您傳遞的X和Y整數坐標。例如:

import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2

pyautogui.moveTo(100, 200)  # moves mouse to X of 100, Y of 200.
pyautogui.rightClick()  # 鼠標原地右鍵單擊

pyautogui.moveTo(800, 800)  # moves mouse to X of 800, Y of 800.
pyautogui.rightClick()  # 鼠標原地右鍵單擊
View Code

通常,鼠標光標會立即移動到新坐標。如果您希望鼠標逐漸移動到新位置,請在移動所需的持續時間(以秒為單位)中傳遞第三個參數。例如:

import pyautogui

pyautogui.moveTo(100, 200)  # moves mouse to X of 100, Y of 200
pyautogui.rightClick()  # 鼠標原地右鍵單擊

pyautogui.moveTo(800, 800, 2)  # moves mouse to X of 800, Y of 800 over 2 seconds
pyautogui.rightClick()  # 鼠標原地右鍵單擊
View Code

如果要將鼠標光標相對於其當前位置(相對位置)移動幾個像素,請使用該move()功能。此函數的參數與相似moveTo()。例如:

import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2

pyautogui.moveTo(140*2, 80*2)  # moves mouse to X of 140*2, Y of 80*2.
pyautogui.rightClick()  # 鼠標原地右鍵單擊

# 從當前位置移動鼠標
pyautogui.move(188*2, 155*2)       # move the mouse left 188*2, down 155*2 pixels.
pyautogui.rightClick()  # 鼠標原地右鍵單擊
View Code

2.3、鼠標拖拽

PyAutoGUI dragTo()drag()函數的參數與moveTo()move()函數的參數相似。此外,它們還有一個button可以設置為'left',的關鍵字'middle',並且'right'在拖動時按住該鼠標鍵不放。例如:

import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2

# button可以設為 left, middle和right
pyautogui.dragTo(35*2, 35*2, button='left')  # drag mouse to X of 35*2, Y of 35*2 while holding down left mouse button
pyautogui.drag(500, 0, 5)  # 按住鼠標左鍵,用5秒鍾把鼠標相對於(35*2, 35*2)往右移動500
View Code

2.4、鼠標點擊

click()功能模擬在鼠標的當前位置單擊鼠標左鍵。“點擊”的定義是按下按鈕然后將其釋放。例如:

pyautogui.click()  # click the mouse

moveTo()在點擊之前合並調用,請為xand y關鍵字參數傳遞整數:

pyautogui.click(x=100, y=200)  # move to 100, 200, then click the left mouse button.

要指定不同的鼠標鍵點擊,傳遞'left''middle''right'button關鍵字參數:

pyautogui.click(button='right')  # right-click the mouse

要進行多次點擊,請將整數傳遞給clicks關鍵字參數。(可選)您可以將float或integer傳遞給interval關鍵字參數,以指定兩次點擊之間的暫停時間(以秒為單位)。例如:

pyautogui.click(clicks=2)  # double-click the left mouse button
pyautogui.click(clicks=2, interval=0.25)  # double-click the left mouse button, but with a quarter second pause in between clicks
pyautogui.click(button='right', clicks=3, interval=0.25)  ## triple-click the right mouse button with a quarter second pause in between clicks

作為便捷的快捷方式,該doubleClick()功能將雙擊鼠標左鍵。它還具有可選xyinterval,和button關鍵字參數。例如:

pyautogui.doubleClick()  # perform a left-button double click
import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2

# pyautogui.moveTo(40*2, 130*2)  # moves mouse to X of 40*2, Y of 40*2.
# pyautogui.doubleClick()  # perform a left-button double click

# pyautogui.doubleClick(40*2, 130*2) # 等價於上面2步
pyautogui.click(40 * 2, 130 * 2, 2, button='left')  # 和上面等價
View Code

2.5、mouseDown()、mouseUp()

鼠標單擊和拖動包括按下鼠標按鈕並向上釋放鼠標按鈕。如果要單獨執行這些操作,請調用mouseDown()mouseUp()函數。它們具有相同的xybutton。例如:

pyautogui.mouseDown(); pyautogui.mouseUp()  # does the same thing as a left-button mouse click
pyautogui.mouseDown(button='right')  # press the right button down
pyautogui.mouseUp(button='right', x=100, y=200)  # move the mouse to 100, 200, then release the right button up.

2.6、鼠標滾動

可以通過調用該scroll()函數並傳遞整數個“單擊”來滾動鼠標滾輪。在不同平台上,“單擊”中的滾動量會有所不同。例如:

import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2

pyautogui.click(300 * 2, 100 * 2)  # 移動到(300*2, 100*2)位置
pyautogui.scroll(-1000)  # 向下滾動1000格
pyautogui.scroll(1000)  # 向上滾動1000格
View Code

2.7、保護措施

Python移動鼠標、點擊鍵盤非常快,有可以導致其他應用出現問題。在這種情況下,程序可能會失控(即使是按照你的意思執行的),那時就需要中斷。如果鼠標還在自動操作,就很難在程序窗口關閉它。

為了能夠及時中斷,PyAutoGUI提供了一個保護措施。當pyautogui.FAILSAFE = True時,如果把鼠標光標在屏幕左上角,PyAutoGUI函數就會產生pyautogui.FailSafeException異常。如果失控了,需要中斷PyAutoGUI函數,就把鼠標光標在屏幕左上角。要禁用這個特性,就把FAILSAFE設置成False

import pyautogui

# 建議PAUSE和FAILSAFE一起使用
# 在每次PyAutoGUI調用(具體的操作)后就會有2秒的暫停
pyautogui.PAUSE = 2
# 將鼠標移動到左上角將引發pyautogui.FailSafeException,可終止程序,設置False禁用此特性
pyautogui.FAILSAFE = False
View Code

2.8、方法、屬性匯總

方法或屬性 作用
pyautogui.PAUSE=2 操作間隔2秒

pyautogui.FAILSAFE = True

開啟故障安全模式

pyautogui.position() 獲取當前鼠標坐標,單位為像素
pyautogui.size() 獲取當前屏幕分辨率,單位為像素

pyautogui.onScreen(x, y)

判斷坐標是否在當前屏幕中,返回值為True和False

pyautogui.moveTo(x, y, duration) 將鼠標移動到指定的 x、y 坐標 (屏幕以左上角為原點(0,0),向下y增加,向右x增加),使用duration值設置幾秒后移動鼠標到指定的 x、y 坐標
pyautogui.move(x, y, duration)

相對於當前的鼠標位置移動鼠標

pyautogui.dragTo(x, y, duration, button) 默認按下左鍵,移動鼠標,button可設置為left, middle和right
pyautogui.drag(x, y, duration, button)

默認按下左鍵,相對於當前位置移動鼠標

pyautogui.click( x, y, clicks=1,button) 模擬點擊(默認是左鍵),clicks=1,2,3(單擊、雙擊、三擊)
pyautogui.rightClick() 模擬右鍵點擊
pyautogui.middleClick() 模擬中鍵點擊
pyautogui.leftClick() 模擬左鍵點擊
pyautogui.doubleClick() 模擬左鍵雙擊
pyautogui.mouseDown(x, y, button)

模擬在 x、y 處按下指定鼠標按鍵

pyautogui.mouseUp(x, y, button)

模擬在 x、y 處釋放指定鍵

pyautogui.scroll(units) 模擬滾動滾輪。正參數表示向上滾動,負參數表示向下滾動。

3、鍵盤操作

3.1、write()

主要鍵盤功能是write()。此函數將在所傳遞的字符串中鍵入字符。要在按下每個字符鍵之間添加延遲間隔,請為interval關鍵字參數傳遞一個int或float值。pyautogui不支持中文輸入,但是可以配合pyperclip模塊進行復制粘貼。

import pyautogui
import pyperclip

# 在每次PyAutoGUI調用(具體的操作)后就會有1秒的暫停
pyautogui.PAUSE = 1

pyautogui.write('Hello world!')  # prints out "Hello world!" instantly
pyautogui.write('Hello world!')
pyautogui.write('傳智播客')  # 不支持中文,不顯示

# 顯示中文的操作
pyperclip.copy('黑馬程序員')
pyautogui.hotkey('ctrl', 'v')  # 按下ctrl+v快捷鍵

# 建議 鼠標要放在這行注釋下方的代碼區 再右鍵運行
View Code

3.2、press()、keyDown()、keyUp()

  • 要按下這些鍵,調用press()函數,從它傳遞一個字符串pyautogui.KEYBOARD_KEYS,例如enterescf1
  • press()函數實際上只是keyDown()keyUp()函數的包裝,它們模擬按下一個鍵然后釋放它。這些功能可以自己調用。
  • 要按類似的方式按多個鍵write(),請將字符串列表傳遞給press()

import pyautogui

# 在每次PyAutoGUI調用(具體的操作)后就會有1秒的暫停
pyautogui.PAUSE = 1

pyautogui.press('enter', presses=3)  # 按下並松開(輕敲)回車鍵(共3次)
pyautogui.write(['enter', 'enter', 'enter'])  # 和上面等價
pyautogui.write('123')

pyautogui.press('enter') # 回車

# 輸出 $ 或 ¥ 符號的按鍵
pyautogui.keyDown('shift')  # 按下`shift`鍵
pyautogui.press('4')
pyautogui.keyUp('shift')  # 松開`shift`鍵

# 建議 鼠標要放在這行注釋下方的代碼區 再右鍵運行
View Code

3.3、hotkey()

為了方便快捷地按下熱鍵或鍵盤快捷鍵,hotkey()可以傳遞幾個鍵字符串,這些字符串將按順序按下,然后以相反的順序釋放。

pyautogui.hotkey('ctrl', 'shift', 'esc')
# 等效於以下代碼:
pyautogui.keyDown('ctrl')
pyautogui.keyDown('shift')
pyautogui.keyDown('esc')
pyautogui.keyUp('esc')
pyautogui.keyUp('shift')
pyautogui.keyUp('ctrl')
View Code

3.4、KEYBOARD_KEYS

以下是有效字符串傳遞給press()keyDown()keyUp(),和hotkey()功能:

['\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']
View Code

3.5、方法、屬性匯總

方法或屬性 作用

pyautogui.KEYBOARD_KEYS

可以控制的按鍵名稱

pyautogui.write(msg) 輸入字符,不支持中文
pyperclip.copy(msg) 復制內容msg,內容可設置為中文等
pyautogui.write([key1,key2]) 鍵入給定鍵字符串,只能是英文
pyautogui.press(key) 按下並釋放給定鍵
pyautogui.keyDown(key) 按住按鍵

pyautogui.keyUp(key)

松開按鍵

pyautogui.hotkey('ctrl', 'v') 模擬按順序按下給定鍵字符串,然后以相反的順序釋放

4、信息框操作

4.1、簡介

PyAutoGUI利用PyMsgBox中的消息框功能提供了一種跨平台的純Python方式來顯示JavaScript樣式的消息框,所有彈窗都會阻塞程序。

4.2、alert()

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

顯示帶有文本和單個“確定”按鈕的簡單消息框。返回單擊的按鈕的文本。

4.3、confirm()

pyautogui.confirm(text='', title='', buttons=['OK', 'Cancel'])

顯示帶有“確定”和“取消”按鈕的消息框。可以自定義按鈕的數量和文本。返回單擊的按鈕的文本。

4.4、prompt()

pyautogui.prompt(text='', title='' , default='')

顯示帶有文本輸入以及“確定”和“取消”按鈕的消息框。返回輸入的文本,如果單擊“取消”,則返回“無”。

4.5、password()

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

顯示帶有文本輸入以及“確定”和“取消”按鈕的消息框。輸入的字符顯示為*。返回輸入的文本,如果單擊“取消”,則返回“無”。

4.6、消息框方法匯總

方法 作用

pyautogui.alert()

簡單提示消息框

pyautogui.confirm() 多按鈕消息框
pyautogui.prompt() 明文輸入消息框
pyautogui.password() 密文輸入消息框

5、截圖定位操作

5.1、簡介

  • PyAutoGUI可以截取屏幕截圖,將其保存到文件中,並在屏幕上定位圖像。如果您有一個很小的圖像,例如需要單擊一個按鈕並想在屏幕上找到它的按鈕,這很有用。
  • 這些功能由PyScreeze模塊提供,該模塊隨PyAutoGUI一起安裝。

  • 屏幕截圖功能需要Pillow模塊。

    • OS X使用操作系統screencapture隨附的命令。
    • Linux使用該scrot命令,可以通過運行進行安裝:sudo apt-get install scrot

5.2、screenshot()

  • 調用screenshot()將返回一個Image對象。傳遞文件名字符串將把屏幕截圖保存到文件中,並將其作為Image對象返回。
  • region如果您不需要整個屏幕的屏幕截圖,則還有一個可選的關鍵字參數。您可以傳遞區域的左側,頂部,寬度和高度的四整數元組來捕獲。

import pyautogui

# 截全屏並設置保存圖片的位置和名稱
im1 = pyautogui.screenshot('./images/screenshot1.png')
print(im1)  # 打印圖片的屬性

# 不截全屏,截取區域圖片。截取區域region參數為:左上角XY坐標值、寬度和高度
pyautogui.screenshot('./images/screenshot2.png', region=(0, 0, 300, 400))

5.3、定位功能

5.3.1、locateOnScreen

  • PyAutoGUI可以通過圖片,在屏幕上定位圖像所在的位置。
  • 調用locateOnScreen(圖片路徑)函數以獲取屏幕圖像坐標,返回值為4整數元組:(左,上,寬度,高度),可以傳遞此元組center()以獲取該區域中心的X和Y坐標。如果沒有找到,返回None

import pyautogui

# 可以通過圖片,在屏幕上定位圖像所在的位置
# 找到返回的是一個4邊距元組 (top, left, width, height),沒有找到返回None
# 全屏幕搜素
rect = pyautogui.locateOnScreen('./images/computer.png')

print(rect)  # Box(left=36, top=222, width=84, height=120)
if rect:  # rect不為None才往下操作
    print(rect[0], rect[1], rect[2], rect[3])  # 36 222 84 120
    x, y = pyautogui.center(rect) # 獲取rect該區域中心的X和Y坐標
    print(x, y)

5.3.2、locateCenterOnScreen

locateCenterOnScreen()函數結合locateOnScreen()center()

import pyautogui

# 可以通過圖片,在屏幕上定位圖像所在的位置,該區域中心的X和Y坐標
point = pyautogui.locateCenterOnScreen('./images/computer.png')

print(point)
if point:  # point不為None才往下操作
    x, y = point
    print(x, y)

5.4、提高定位精度

可選的confidence關鍵字參數指定函數在屏幕上定位圖像的精度

  • 這個參數范圍和環境有關,需要在0~1之間調試最佳參數
  • 需要安裝OpenCV才能使confidence關鍵字起作用:pip install opencv-python

import pyautogui

# 可以通過圖片,在屏幕上定位圖像所在的位置
# 找到返回的是一個4邊距元組 (top, left, width, height),沒有找到返回None
# 全屏幕搜素
rect = pyautogui.locateOnScreen('./images/x3.png', confidence=0.6)
print(rect)

5.5、加速定位

  • 指定搜索區域
pyautogui.locateOnScreen('./images/computer.png', region=(0, 0, 400, 400))
  • (可選)可以傳遞grayscale=True給locate函數以略微加快速度(大約30%-ish)。這會使圖像和屏幕截圖的顏色降低飽和度,從而加快定位速度。
pyautogui.locateOnScreen('./images/computer.png', grayscale=True)

5.6、方法匯總

方法 匯總
pyautogui.screenshot() 截屏
pyautogui.locateOnScreen() 從屏幕尋找圖片位置,返回一個4邊距坐標
pyautogui.locateCenterOnScreen() 從屏幕尋找圖片位置,返回中心點坐標

6、案例:自動寫字表白

  • 自動打開記事本
  • 自動寫字 如花,今晚看電影如何?今晚剛好敲完代碼!!,每隔0.3秒寫一個字
  • 自動保存文件
  • 自動關閉記事本

參考代碼:

import pyautogui
import os
import multiprocessing
import time
import pyperclip


# 進程處理函數
def start_notepad():
    os.system('notepad')  # 阻塞,不按關閉,不會往下執行


def write_word(words, t=0.1):
    for v in words:
        pyperclip.copy(v)
        pyautogui.hotkey('ctrl', 'v')
        time.sleep(t)


def main():
    # 1. 創建進程
    p = multiprocessing.Process(target=start_notepad)
    # 2. 進程啟動
    p.start()

    time.sleep(1)

    # 2.1 定位軟件
    point = pyautogui.locateCenterOnScreen('./love_imgs/note2.png', confidence=0.6)
    print(point)
    pyautogui.click(point.x, point.y)

    time.sleep(0.5)

    # 3. 寫字
    write_word('如花,今晚看電影如何?今晚剛好敲完代碼!!', 0.3)

    # 4. 保存文件
    pyautogui.hotkey('ctrl', 's')

    time.sleep(1)
    # 5. 寫字,保存文件的文件名
    write_word('表白記錄.txt', 0.2)

    # 6. 回車
    pyautogui.press('enter')

    # 7. 按個y確定保存
    pyautogui.press('y')

    time.sleep(1)

    # 8. 關閉當前的pycharm
    pyautogui.hotkey('alt', 'f4')

    time.sleep(1)

    # 9. 關閉記事本軟件
    pyautogui.hotkey('alt', 'f4')


if __name__ == '__main__':
    main()
View Code


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM