自动化测试之桌面自动化(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

posted on 2020-10-28 08:44  yycnblog  阅读(3913)  评论(0编辑  收藏  举报

导航