文章目录
pyautogui 模块包含了一些函数,可以让你的Python脚本控制鼠标移动、按键和滚动鼠标滚轮。
window上直接运行pip install pyautogui即可安装PyAutoGUI模块。
如果你的程序出了问题,程序可能失去控制,但你的程序继续到处移动鼠标,停止它可能很难,所以需要有方法来强制停止程序。
通过注销关闭所有程序
停止失去控制的 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,启动自动防故障功能。
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()
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)
通过调用 pyautogui.position() 函数,可以确定鼠标当前的位置。它将返回函数调用时,鼠标 x、y 坐标的元组:
>>> pyautogui.position()
(311, 622)
>>> pyautogui.position()
(377, 481)
>>> pyautogui.position()
(1536, 637)
要向计算机发送虚拟的鼠标点击,就调用 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() 函数将分别执行双击右键和双击中键。
“拖动”意味着移动鼠标,同时按住一个按键不放。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将绘制一个正方形旋转图:

滚动鼠标的函数是 scroll(),传递正整数表示向上滚动,传递负整数表示向下滚动。
>>> pyautogui.scroll(200)
pyautogui 拥有屏幕快照的功能,可以根据当前屏幕的内容创建图形文件。
要在 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 个整数,表示像素的红绿蓝值。
如果屏幕上指定的 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。
如果事先不知道应该点击哪里,怎么办?可以使用图像识别,向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))
如下代码Python 首先在坐标(100,100)处发出虚拟鼠标点击,这将点击文件编辑窗口,让它获得焦点。typewrite() 函数调用将向窗口发送文本 Hello world!
>>> pyautogui.click(100, 100); pyautogui.typewrite('Hello world!', 0.25)

除了单个字符串参数,还可以向 typewrite() 函数传递这些键字符串的列表。例如,以下的调用表示按 a 键,然后是 b 键,然后是左箭头两次,最后是 X 和 Y 键:
>>> pyautogui.typewrite(['a', 'b', 'left', 'left', 'X', 'Y'])
因为按下左箭头将移动键盘光标,所以这会输出 XYab。
下表列出了 pyautogui的键盘键字符串,你可以将它们传递给 typewrite() 函数,模拟任何按键组合。也可以查看 pyautogui.KEYBOARD_KEYS 列表,看看 pyautogui 接受的所有可能的键字符串。


就像 mouseDown() 和 mouseUp() 函数一样,pyautogui.keyDown() 和 pyautogui.keyUp() 将向计算发送虚拟的按键和释放。方便起见,pyautogui 还提供了pyautogui.press() 函数,它调用这两个函数,模拟完整的击键。
运行下面的代码,它将打印出美元字符(通过按住 Shift 键并按 4 得到):
>>> pyautogui.keyDown('shift'); pyautogui.press('4'); pyautogui.keyUp('shift')
如果你需要在文本输入框内打一个字符串,typewrite() 函数就更适合。但对于接受单个按键命令的应用,press() 函数是更简单的方式。
拷贝选择内容的常用热键是 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')

>>> 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.
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
当我在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)(人们推荐的最少
我正在使用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.
我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新rubygems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我正在尝试在Ruby中制作一个cli应用程序,它接受一个给定的数组,然后将其显示为一个列表,我可以使用箭头键浏览它。我觉得我已经在Ruby中看到一个库已经这样做了,但我记不起它的名字了。我正在尝试对soundcloud2000中的代码进行逆向工程做类似的事情,但他的代码与SoundcloudAPI的使用紧密耦合。我知道cursesgem,我正在考虑更抽象的东西。广告有没有人见过可以做到这一点的库或一些概念证明的Ruby代码可以做到这一点? 最佳答案 我不知道这是否是您正在寻找的,但也许您可以使用我的想法。由于我没有关于您要完成的工作
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or