Python进阶教程m8b–pyautogui–键盘鼠标截屏

原文链接:http://www.juzicode.com/archives/3560

pyautogui可以用来控制键盘鼠标模拟人为操作,从而实现某些需要人工操作才能控制的场景,比如某些应用软件的测试、不适合爬虫的网页内容获取等场景。还可以用来截取屏幕,它附带了简单的图像识别功能,通过事先保存的模板图片,在屏幕上匹配该模板图片得到屏幕位置,再传递给鼠标控制函数实现点击、输入操作。

pyautogui不是Python标准库,需要先安装:

pip install pyautogui

1、屏幕大小、位置

使用size()方法获取屏幕大小:

import pyautogui

scr_w, scr_h = pyautogui.size() #获取屏幕大小
print('scr_w, scr_h:', scr_w, scr_h)

===========运行结果:
scr_w, scr_h: 1920 1080

使用onScreen()方法判断某个坐标值是否在屏幕内:

ret = pyautogui.onScreen(0, 0)
print('0,0 是否在屏幕内:',ret)
ret = pyautogui.onScreen(2000, 2000)
print('2000,2000 是否在屏幕内:',ret)

===========运行结果:
0,0 是否在屏幕内: True
2000,2000 是否在屏幕内: False

2、鼠标操作

a、position() 获取当前鼠标位置

使用position()方法获取当前鼠标的位置,位置值从屏幕的左上角向右下角方向增加:

mouse_x, mouse_y = pyautogui.position() # 获取鼠标位置
print('mouse_x, mouse_y:',mouse_x, mouse_y)

===========运行结果:
mouse_x, mouse_y: 803, 235

b、move(),moveTo() 移动鼠标

move()方法按照传入的像素值移动这些像素个数,是一种相对位置移动方法。moveTo则需要指定要移动到哪个位置,是一种绝对位置移动方法。这2种方法都带3个参数,第1个是水平方向,第2个表示垂直方向,第3个表示这个移动过程所需要的时间,也不可以不带第3个参数。移动方向的参数可以是None,表示不改变这个方向的值,表现为只在水平方向移动或者只在垂直方向移动。

#移动到屏幕x=500,y=300的位置,耗时0.5s
pyautogui.moveTo(500, 300,0.5)  

#移动向右x=50,向下y=30,耗时1s
pyautogui.move(50, 30,1)  

#显示当前鼠标的位置
mouse_x, mouse_y = pyautogui.position() # 获取鼠标位置
print('mouse_x, mouse_y:',mouse_x, mouse_y)

===========运行结果:
mouse_x, mouse_y: 530, 330

c、drag(),dragTo() 拖曳鼠标

drag(),dragTo()用法和move(),moveTo()类似,表示移动鼠标并拖曳鼠标,入参多了个button传入要点击的是哪个按键进行拖曳,可以是left,right,middle。

#点击左键拖曳移动到屏幕x=500,y=300的位置, 耗时0.5s
pyautogui.dragTo(500, 300,0.5,button='left')  
time.sleep(2)
#移动向右x=50,向下y=30,耗时1s
pyautogui.drag(50, 30, button='left')  
#显示当前鼠标的位置
mouse_x, mouse_y = pyautogui.position() # 获取鼠标位置
print('mouse_x, mouse_y:',mouse_x, mouse_y)
 
===========运行结果:
mouse_x, mouse_y: 530, 330

d、click() 点击鼠标

click()方法实现点击鼠标,如果传入x,y的值表示移动到该位置后点击,如果传入鼠标的按键入参button,可以有left,right,middle,表示移动后并点击某个鼠标按键。可以只传入x,y的值表示移动鼠标,也可以只传入button的值表示在当前位置进行鼠标按键。

#移动到屏幕x=500,y=600的位置,并点击右键 
pyautogui.click(x=500, y=600,button='right')  

可以传入点击次数clicks 和点击的时间间隔 interval :

#移动到屏幕x=500,y=600的位置,间隔0.1s,连续点击鼠标左键2次 
pyautogui.click(x=500, y=600,clicks=2,interval=0.1)  

可以传入参数button,表示要点击的按键,没有传参时默认点击的是left键:

#移动到屏幕x=500,y=600的位置,间隔0.1s,连续点击鼠标左键3次 
pyautogui.click(x=500, y=600,clicks=3,interval=0.1,button='left')  

另外还有 doubleClick()、tripleClick()、rightClick()等对click()方法进一步封装的用法。

e、scroll() 滑动鼠标

scroll()可以用来滑动鼠标,正值表示向上滑动,负值表示向下滑动

pyautogui.scroll(-500) 
time.sleep(1) 
pyautogui.scroll(500)  

3、键盘

a、write() 多个按键

写入一个字符串,还可以传入interval表示写入每个字符之间的间隔。

time.sleep(1)
pyautogui.write('www.juzicode.com', interval=0.25)

b、press() 单个或多个按键

press()是对 keyDown() and keyUp() 的封装,键盘上的一个按键动作可以分解为按下 keyDown() 和释放 keyUp() 。

press()传入单个字符表示单个按键,用入参presses=N传入连续输入的单个字符的次数,另外也可以用一个list表示要传入的是多个字符。

pyautogui.press('j', presses=5) 
pyautogui.press(['j','u','z','i']) 

如果想用press()方法传入多个字符,比如下面这个例子中第2行想同时输入”juzi”4个字符,实际上得不到想要的结果:

pyautogui.press('x', presses=5) 
pyautogui.press('juzi') 
pyautogui.press('y', presses=5) 

==========运行结果:
xxxxxyyyyy

这是因为press的入参形式是有约定的,必须是在pyautogui.KEY_NAMES中定义的字符串,如果不是这些字符串则不做处理,从下面打印出来的信息可以看到大部分的单字母、数字都是和键盘上的按键一样的:

 print('pyautogui.KEY_NAMES:\n',pyautogui.KEY_NAMES)

[‘\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’]

如果配合shift键的使用,可以先用KeyDown(),再使用press(),最后使用keyUp(),下面这个例子实际连续输入的是2个字符*:

pyautogui.keyDown('shift')   
pyautogui.press('8')     
pyautogui.press('8')    
pyautogui.keyUp('shift')   

c、hotkey() 热键

hotkey()用来传入组合按键,按照传入的入参顺序按下键,然后按照相反的顺序释放键,下面这个例子在windows系统中调出任务管理器:

time.sleep(1)
pyautogui.hotkey('ctrl', 'shift', 'esc')

4、截屏、查找模板图片位置

a、screenshot() 截图

利用screenshot()方法截图返回的是一个PIL实例,如果带路径和文件名参数可以保存到本地,也可以用region=( left, top, width,height )指明截图的区域。

img = pyautogui.screenshot()
print(img)
img = pyautogui.screenshot('截图1.png')
print(img)
img = pyautogui.screenshot('截图2.png',region=(0,0, 800, 500))
print(img)

==========运行结果:
<PIL.Image.Image image mode=RGB size=1920x1080 at 0x2E537A680A0>
<PIL.Image.Image image mode=RGB size=1920x1080 at 0x2E537A68040>
<PIL.Image.Image image mode=RGB size=800x500 at 0x2E5379FEBE0>

下图是指定region截图的效果:

b、locateCenterOnScreen() 定位模板中心点

使用locateCenterOnScreen()定位函数可以根据输入的模板图片在屏幕上查找位置,下面这个例子中实现在屏幕上查找模板图片start.png所在的位置并点击该位置:

import pyautogui
x, y = pyautogui.locateCenterOnScreen('start.png')
print('start.png在当前屏幕位置:',x,y)
pyautogui.click(x,y)

模板图片start.png:

要查找的屏幕:

前面的例子中如果查找成功,则会点击start位置。如果没有找到模板图片,则会抛异常:

Traceback (most recent call last):
  File "pyautogui-截图2.py", line 11, in <module>
    x, y = pyautogui.locateCenterOnScreen('start.png')
TypeError: cannot unpack non-iterable NoneType object

locateCenterOnScreen()查找到位置,再使用click()方法点击该位置的2个步骤也可以合为一个,直接用模板图片的文件名称传递给click()方法,比如上面的例子等价于:

pyautogui.click('start.png')

c、locateOnScreen() 查找屏幕位置

locateOnScreen()查找模板图片在屏幕的位置,返回的是一个box实例,包含left, top, width, height 属性,如果要点击模板图片的中心可以根据各个属性的值计算:centerx,centery = left + width/2 , top + height/2,也可以调用center()方法直接得到结果,这个计算的结果可以传递给click()方法点击:

import pyautogui
box = pyautogui.locateOnScreen('start.png')
print('start.png在当前屏幕位置:',box)
center = pyautogui.center(box)
print('start.png在当前屏幕位置中心点:',center)

=========运行结果:
start.png在当前屏幕位置: Box(left=637, top=316, width=209, height=69)
start.png在当前屏幕位置中心点: Point(x=741, y=350)

d、locateAllOnScreen() 查找所有位置

locateOnScreen()只返回模板图片在屏幕中的第1个位置,如果需要返回屏幕可能的多个位置,则需要用locateAllOnScreen(),返回的是一个生成器,可以用for循环迭代,也可以用list()生成一个列表。

for pos in pyautogui.locateAllOnScreen('someButton.png')
    print(pos)
list(pyautogui.locateAllOnScreen('someButton.png'))

==========运行结果 
(101, 1345, 82, 66)
(159, 451, 150, 53)

[(101, 1345, 82, 66), (159, 451, 150, 53)]

e、pixel() 获取像素值

pixel()可以获取指定屏幕位置的RGB值:

import pyautogui
rgb = pyautogui.pixel(100,200)
print('该位置的像素值:',rgb)

==========运行结果:
该位置的像素值: (158, 221, 236)

5、弹窗

调用弹窗类的方法可以通过弹窗打印提示信息或者获取到输入内容。

a、alert()

alert()方法显示弹窗消息,text入参为窗口消息,title为窗口标题:

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

弹窗例子:

pyautogui.alert(text='这是一个pyautogui例子', title='#vx:桔子code # juzicode.com')

b、confirm()

confirm()方法也可以显示弹窗消息 ,用法和alert()类似,不过可以选择不同的按钮,窗口关闭后能返回具体是哪个按键被点击了,buttons入参可以定制按键的数量和内容:

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

弹窗例子:

print('\n-----欢迎来到www.juzicode.com')
print('-----公众号: 桔子code/juzicode \n')   

import pyautogui

ret=pyautogui.confirm(text='这是一个confirm例子', title='#vx:桔子code # juzicode.com',buttons=['是','否'])
print('弹窗按键:',ret)

==========运行结果:
-----欢迎来到www.juzicode.com
-----公众号: 桔子code/juzicode

弹窗按键: 是

c、promot()

promot()弹框可以获取输入,如果点击OK按钮窗口关闭后返回的值就是在窗口中输入的值,如果点击Cancel按钮返回None:

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

例子:

import pyautogui
ret=pyautogui.prompt(text='这是一个prompt例子', title='#vx:桔子code # juzicode.com')
print('弹窗输入:',ret)

==========运行结果:
弹窗输入: 这是在窗口中输入的内容

d、password()

 password()和promot()类似用法,顾名思义就是可以获取输入密码,不过输入的内容会自动被“*”替代,如果修改mask的值,*将会被修改后的值替代:

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

弹窗例子:

import pyautogui
ret=pyautogui.password(text='这是一个password例子', title='#vx:桔子code # juzicode.com')
print('弹窗输入:',ret)

==========运行结果:
弹窗输入: thisisapassword

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注