草庐IT

Python PyAutoGUI模块自动化控制鼠标和键盘

独在黑夜_看湖面 2023-05-03 原文

文章目录


1. PyAutoGUI安装

pyautogui 模块包含了一些函数,可以让你的Python脚本控制鼠标移动、按键和滚动鼠标滚轮。

window上直接运行pip install pyautogui即可安装PyAutoGUI模块。


2. 程序失去控制时如何终止程序

如果你的程序出了问题,程序可能失去控制,但你的程序继续到处移动鼠标,停止它可能很难,所以需要有方法来强制停止程序。

  • 通过注销关闭所有程序
    停止失去控制的 GUI 自动化程序,最简单的方法可能是注销,在 Windows 和 Linux 上,注销的热键是 Ctrl-Alt-Del

  • 将鼠标移动到屏幕左上角,故意触发异常
    pyautogui 也有自动防故障功能,如果你尽可能快地向左上移动鼠标,自动防故障功能都将停止程序。即如果将鼠标移到屏幕的左上角,将导致 pyautogui产生 pyautogui .FailSafeException 异常,终止程序。

>>> import pyautogui
>>> pyautogui.PAUSE = 1
>>> pyautogui.FAILSAFE = True

这里我们导入 pyautogui,并将 pyautogui.PAUSE 设置为 1,即每次函数调用后暂停一秒。将 pyautogui.FAILSAFE 设置为 True,启动自动防故障功能。


3. 控制鼠标移动

pyautogui 的鼠标函数使用 x、y 坐标,下图中展示了计算机屏幕的坐标系统。原点的 x、y 都是零,在屏幕的左上角。向右 x 坐标增加,向下 y 坐标增加。所有坐标都是正整数,没有负数坐标。

分辨率是屏幕的宽和高有多少像素。如果屏幕的分辨率设置为 1920 ×1080,那么左上角的坐标是(0,0),右下角的坐标是(1919,1079)。

pyautogui.size() 函数返回两个整数的元组,包含屏幕的宽和高的像素数:

>>> import pyautogui
>>> pyautogui.size()
(1920, 1080)
>>> width, height = pyautogui.size()

3.1 移动鼠标

pyautogui.moveTo() 函数将鼠标立即移动到屏幕的指定位置。表示 x、y 坐标的整数值分别构成了函数的第一个和第二个参数。可选的 duration 整数或浮点数关键字参数,指定了将鼠标移到目的位置所需的秒数。如果不指定,默认值是零,表示立即移动:

>>> import pyautogui
>>> for i in range(10):
 pyautogui.moveTo(100, 100, duration=0.25)
 pyautogui.moveTo(200, 100, duration=0.25)
 pyautogui.moveTo(200, 200, duration=0.25)
 pyautogui.moveTo(100, 200, duration=0.25)

pyautogui.moveRel() 函数相对于当前的位置移动鼠标。下面的例子以正方形的模式移动鼠标,只是它从鼠标当前所在的位置开始,按正方形移动:

>>> import pyautogui
>>> for i in range(10):
 pyautogui.moveRel(100, 0, duration=0.25)
 pyautogui.moveRel(0, 100, duration=0.25)
 pyautogui.moveRel(-100, 0, duration=0.25)
 pyautogui.moveRel(0, -100, duration=0.25)

3.2 获取鼠标位置

通过调用 pyautogui.position() 函数,可以确定鼠标当前的位置。它将返回函数调用时,鼠标 x、y 坐标的元组:

>>> pyautogui.position()
(311, 622)
>>> pyautogui.position()
(377, 481)
>>> pyautogui.position()
(1536, 637)

4. 控制鼠标交互

4.1 点击鼠标

要向计算机发送虚拟的鼠标点击,就调用 pyautogui.click() 方法。默认情况下,点击将使用鼠标左键,点击发生在鼠标当前所在位置。如果希望点击在鼠标当前位置以外的地方发生,可以传入 x、y 坐标作为可选的第一第二参数。

如果想指定鼠标按键,就加入 button 关键字参数,值分别为 'left''middle' 'right'。例如,pyautogui.click(100,150,button='left')将在坐标(100,150)处点击鼠标左键。而 pyautogui.click(200,250,button='right')将在坐标(200,250)处点击右键。

>>> import pyautogui
>>> pyautogui.click(10, 5)

另外,pyautogui.doubleClick() 函 数执 行 双 击 鼠 标 左 键 。pyautogui.rightClick()pyautogui.middleClick() 函数将分别执行双击右键和双击中键。

4.2 拖动鼠标

“拖动”意味着移动鼠标,同时按住一个按键不放。PyAutoGUI 提供了 pyautogui.dragTo() pyautogui.dragRel() 函数,将鼠标拖动到一个新的位置,或相对当前位置的位置。 dragTo() 和 dragRel() 的参数与moveTo() 和 moveRel() 相同:x 坐标/水平移动,y 坐标/垂直移动,以及可选的时间间隔。

举例:请打开 Windows 上的画图软件,让鼠标停留在绘图应用的画布上,同时选中铅笔或画笔工具,在新的文件编辑窗口中输入以下内容,保存为 spiralDraw.py:

import pyautogui, time
time.sleep(5)
pyautogui.click() # click to put drawing program in focus
distance = 200
while distance > 0:
	pyautogui.dragRel(distance, 0, duration=0.2) # move right 
	distance = distance - 5 
	pyautogui.dragRel(0, distance, duration=0.2) # move down 
	pyautogui.dragRel(-distance, 0, duration=0.2) # move left 
	distance = distance - 5 
	pyautogui.dragRel(0, -distance, duration=0.2) # move up 

在运行这个程序时,会有 5 秒钟的延迟,让你选中铅笔或画笔工具,并让鼠标停留在画图工具的窗口上。spiralDraw.py将绘制一个正方形旋转图:

4.3 滚动鼠标

滚动鼠标的函数是 scroll(),传递正整数表示向上滚动,传递负整数表示向下滚动。

>>> pyautogui.scroll(200)

5. 处理屏幕

pyautogui 拥有屏幕快照的功能,可以根据当前屏幕的内容创建图形文件。

5.1 获取屏幕快照

要在 Python 中获取屏幕快照,就调用 pyautogui.screenshot() 函数:

>>> import pyautogui
>>> im = pyautogui.screenshot()

im 变量将包含一个屏幕快照的 Image 对象。现在可以调用 im 变量中 Image 对象的方法,就像所有其他 Image 对象一样:

>>> im.getpixel((0, 0))
(176, 176, 175)
>>> im.getpixel((50, 200))
(130, 135, 144)

getpixel() 函数传入坐标元组,如(0,0)或(50,200),它将告诉你图像中这些坐标处的像素颜色。getpixel() 函数的返回值是一个 RGB 元组,包含 3 个整数,表示像素的红绿蓝值。

5.2 分析屏幕快照

如果屏幕上指定的 x、y 坐标处的像素与指定的颜色匹配,PyAutoGUI 的pixelMatchesColor() 函数将返回 True。pixelMatchesColor() 函数第一和第二个参数是整数,对应 x 和 y 坐标。第三个参数是一个元组,包含 3 个整数,是屏幕像素必须匹配的 RGB 颜色:

>>> import pyautogui
>>> im = pyautogui.screenshot()
>>> im.getpixel((50, 200))
(130, 135, 144)
>>> pyautogui.pixelMatchesColor(50, 200, (130, 135, 144))
True
>>> pyautogui.pixelMatchesColor(50, 200, (255, 135, 144))
False

给定坐标处的颜色应该“完全”匹配。即使只是稍有差异,那么函数也会返回 False。


6. 图像识别

如果事先不知道应该点击哪里,怎么办?可以使用图像识别,向PyAutoGUI 提供希望点击的图像,让它去弄清楚坐标。

例如,如果你以前获得了屏幕快照,截取了提交按钮的图像,保存为submit.png,那么 locateOnScreen() 函数将返回图像所在处的坐标:

>>> import pyautogui
>>> pyautogui.locateOnScreen('submit.png')
(643, 745, 70, 29)

locateOnScreen() 函数返回4个整数的元组,是屏幕上首次发现该图像时左边的x 坐标、顶边的 y 坐标、宽度以及高度。如果屏幕上找不到该图像,locateOnScreen() 函数将返回 None

在得到图像所在屏幕区域的 4 整数元组后,就可以点击这个区域的中心。将元组传递给center()函数,它将返回该区域中心的 x、y 坐标。用center()得到中心坐标后,将 click() 坐标传递给函数,就会点击屏幕上该区域的中心,这个区域匹配你传递给 locateOnScreen() 函数的图像:

>>> pyautogui.locateOnScreen('submit.png')
(643, 745, 70, 29)
>>> pyautogui.center((643, 745, 70, 29))
(678, 759)
>>> pyautogui.click((678, 759))

7. 控制键盘

7.1 通过键盘发送一个字符串

如下代码Python 首先在坐标(100,100)处发出虚拟鼠标点击,这将点击文件编辑窗口,让它获得焦点。typewrite() 函数调用将向窗口发送文本 Hello world!

>>> pyautogui.click(100, 100); pyautogui.typewrite('Hello world!', 0.25)

7.2 键名

除了单个字符串参数,还可以向 typewrite() 函数传递这些键字符串的列表。例如,以下的调用表示按 a 键,然后是 b 键,然后是左箭头两次,最后是 X 和 Y 键:

>>> pyautogui.typewrite(['a', 'b', 'left', 'left', 'X', 'Y'])

因为按下左箭头将移动键盘光标,所以这会输出 XYab。

下表列出了 pyautogui的键盘键字符串,你可以将它们传递给 typewrite() 函数,模拟任何按键组合。也可以查看 pyautogui.KEYBOARD_KEYS 列表,看看 pyautogui 接受的所有可能的键字符串。

7.3 按下和释放键盘

就像 mouseDown() mouseUp() 函数一样,pyautogui.keyDown()pyautogui.keyUp() 将向计算发送虚拟的按键和释放。方便起见,pyautogui 还提供了pyautogui.press() 函数,它调用这两个函数,模拟完整的击键。

运行下面的代码,它将打印出美元字符(通过按住 Shift 键并按 4 得到):

>>> pyautogui.keyDown('shift'); pyautogui.press('4'); pyautogui.keyUp('shift')

如果你需要在文本输入框内打一个字符串,typewrite() 函数就更适合。但对于接受单个按键命令的应用,press() 函数是更简单的方式。

7.4 热键组合

拷贝选择内容的常用热键是 Ctrl-C,用户按住Ctrl键,然后按C键,然后释放C和Ctrl键。要用pyautogui的keyDown()keyUp() 函数来做到这一点,必须输入以下代码:

pyautogui.keyDown('ctrl')
pyautogui.keyDown('c')
pyautogui.keyUp('c')
pyautogui.keyUp('ctrl')

这相当复杂。作为替代,可以使用 pyautogui.hotkey() 函数,它接受多个键字符串参数,按顺序按下,再按相反的顺序释放:

pyautogui.hotkey('ctrl', 'c')

8. 复习 PyAutoGUI 的函数

8.1 PyAutoGUI 常用函数

8.2 PyAutoGUI函数用法举例

>>> import pyautogui

>>> screenWidth, screenHeight = pyautogui.size() # Get the size of the primary monitor.
>>> screenWidth, screenHeight
(2560, 1440)

>>> currentMouseX, currentMouseY = pyautogui.position() # Get the XY position of the mouse.
>>> currentMouseX, currentMouseY
(1314, 345)

>>> pyautogui.moveTo(100, 150) # Move the mouse to XY coordinates.

>>> pyautogui.click()          # Click the mouse.
>>> pyautogui.click(100, 200)  # Move the mouse to XY coordinates and click it.
>>> pyautogui.click('button.png') # Find where button.png appears on the screen and click it.

>>> pyautogui.move(400, 0)      # Move the mouse 400 pixels to the right of its current position.
>>> pyautogui.doubleClick()     # Double click the mouse.
>>> pyautogui.moveTo(500, 500, duration=2, tween=pyautogui.easeInOutQuad)  # Use tweening/easing function to move mouse over 2 seconds.

>>> pyautogui.write('Hello world!', interval=0.25)  # type with quarter-second pause in between each key
>>> pyautogui.press('esc')     # Press the Esc key. All key names are in pyautogui.KEY_NAMES

>>> with pyautogui.hold('shift'):  # Press the Shift key down and hold it.
        pyautogui.press(['left', 'left', 'left', 'left'])  # Press the left arrow key 4 times.
>>> # Shift key is released automatically.

>>> pyautogui.hotkey('ctrl', 'c') # Press the Ctrl-C hotkey combination.

>>> pyautogui.alert('This is the message to display.') # Make an alert box appear and pause the program until OK is clicked.

9. PyAutoGUI参考资料

  1. PyAutoGUI官方文档

有关Python PyAutoGUI模块自动化控制鼠标和键盘的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  5. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  6. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  7. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  8. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  9. ruby - 在 Ruby 中用键盘诅咒数组浏览 - 2

    我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作

  10. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

随机推荐