1. 简介
开篇先放两个自动化操作鼠标的案例:
自动玩咸鱼之王开宝箱
自动控制鼠标绘制图形
在工作和游戏中,处理重复性任务常常令人头疼,我们可以使用 PyAutoGUI 将重复性工作转化为自动化脚本
github:github.com/asweigart/p…
文档:pyautogui.readthedocs.io/en/latest/
PyAutoGUI:Py 指的是 Python,Auto:自动,GUI:图形用户界面,所以 PyAutoGUI 从名字上就能看出来,PyAutoGUI 就是 Python 自动化图形界面(采用图形方式显示的计算机操作)
PyAutoGUI 是一个电脑端的 Python 自动化工具。它能控制鼠标和键盘进行电脑操作,适合执行重复性高的固定流程的任务,将繁杂的机械化操作转化为自动化脚本。可以写自动化办公和游戏脚本,模拟人类手动操作(鼠标和键盘)的行为,解放双手。理论上需要人工进行的大量重复的工作,都能用自动化来实现。
并且 PyAutoGUI 自带屏幕截图和图像识别功能,相当于给程序安装了眼睛,能自动识别并定位到图片(基于当前屏幕获取坐标)。有了手脚(鼠标和键盘) + 眼睛(图片识别和定位),可谓是如虎添翼,发挥想象力,能实现许多有趣且有用的功能;还可以安装 OpenCV 与 YOLO 实现更复杂的图像识别,以及结合 OCR 文本识别(读取图片内容),构建更强大的自动化解决方案。
注意:
-
PyAutoGUI 只能在 Windows、macOS 和 Linux 系统上运行,不支持在 Android、iOS 或平板电脑/智能手机应用程序上运行
-
PyAutoGUI 模拟的是真实的人工操作,无法进行后台操作,不能最小化窗口,目标窗口不能被遮挡
-
PyAutoGUI 不支持多显示屏,为了避免报错或程序不生效,请在主屏幕内进行操作
2. 安装
我使用 uv 作为 python 包管理工具。为了节省文章篇幅,安装 uv,使用 uv 安装 python 以及创建项目,创建虚拟环境等步骤略过,不会 uv 的同学可以看我的另一篇文章:
📝 《Python 入门(一)- 用 UV 管理 Python》:juejin.cn/post/760585…
安装 PyAutoGUI 库
uv add pyautogui
安装后会在 pyproject.toml 文件写入 PyAutoGUI 依赖和在 uv.lock 文件锁定 PyAutoGUI 包的版本
PyAutoGUI 会安装它所依赖的模块,包括 PyTweening、PyScreeze、PyGetWindow、PymsgBox 和 MouseInfo,在 uv.lock 文件中搜索可以看见这些模块,就不一一列举展示了
3. 鼠标控制
3.1 获取屏幕分辨率
用 size() 函数获取当前屏幕分辨率
在项目根目录下面创建一个名为 main.py 的文件,内容如下
import pyautogui as pag
screen = pag.size()
print(screen)
运行 main.py 文件,查看效果
uv run main.py
代码解释:
-
import pyautogui:引入 PyAutoGUI 库
-
as pag:给引入的库(pyautogui)赋值一个别名(pag)
-
screen = pag.size():调用 pag.size() 方法,将返回值赋值给 screen 变量
-
print(screen):打印 screen 变量
3.2 获取鼠标的坐标
用 position() 函数获取鼠标光标的当前 X 和 Y 坐标
main.py:
import pyautogui as pag
x, y = pag.position()
print(f"X: {x}, Y: {y}")
运行 main.py:
uv run main.py
3.3 鼠标移动
3.3.1 基于屏幕移动
用 moveTo() 函数,将鼠标光标移动到你传入的 X 和 Y 坐标处(以屏幕左上角为坐标原点)
main.py:
import pyautogui as pag
pag.moveTo(100, 100, duration=3)
运行 main.py:
uv run main.py
代码执行后,在 3 秒单位的时间长度上,均匀的将鼠标移动到屏幕 X 轴 100 像素的距离,Y 轴 100 像素的距离的位置
代码解释:
-
屏幕左上角为坐标原点(0,0)
-
X 坐标:从左侧的 0 开始,向右增加
-
Y 坐标:从顶部的 0 开始,向下增加
-
duration:程序执行的时间(单位秒)
注意:x 和 Y 坐标的数值不能大于当前屏幕分辨率,否则会报错,可以用 size() 函数检测当前屏幕的分辨率,x 和 Y 坐标的数值范围是 0 - (分辨率-1);比如我当前屏幕分辨率为 宽=2560,高=1600,那么我 x 最小值为0,最大值为 2559。Y 最小值为0,最大值为 1599
3.3.2 基于鼠标位置移动
用 move() 函数,将鼠标光标移动到您传入的 X 和 Y 坐标处(以当前鼠标光标的位置为坐标原点)
main.py:
import pyautogui as pag
pag.move(200, 200, duration=3)
运行 main.py:
uv run main.py
3.4 鼠标点击
用 click() 函数模拟鼠标点击操作(默认鼠标左键)
3.4.1 单击(在当前位置)
import pyautogui as pag
pag.click()
3.4.2 单击(在指定位置)
在传入的 x 和 y 轴坐标位置单击
import pyautogui as pag
pag.click(x=600, y=300)
3.4.3 单击(在指定位置,指定次数)
在传入的 x 和 y 轴坐标位置,单击两次(clicks:点击次数)
import pyautogui as pag
pag.click(x=600, y=300, clicks=2)
3.4.4 单击(在指定位置,指定次数,指定点击间隔)
在传入的 x 和 y 轴坐标位置),单击两次(clicks:点击次数),每次点击间隔 0.25 秒(interval:间隔时间,单位秒)
import pyautogui as pag
pag.click(x=50, y=200, clicks=2, interval=0.25)
我在桌面左上角新建了一个文本文件,执行代码将鼠标移动到左上角并双击打开此文本文件
3.4.5 单击(鼠标右键)
鼠标右键单击(在传入的 x 和 y 轴坐标位置);button:位置,默认为 'left', 可选值有 'left' 、 'middle' 、 'right'
import pyautogui as pag
pag.click(x=50, y=200, button="right")
3.4.6 单击(鼠标右键,鼠标移动时间)
跟鼠标移动一样,鼠标点击也可以加上 duration 参数
import pyautogui as pag
pag.click(x=50, y=200, button="right", duration=3)
代码表示:鼠标花 3 秒的时间移动到 x=50, y=200 坐标,然后点击鼠标右键
3.5 鼠标按住和抬起
3.5.1 鼠标左键按下/抬起
将鼠标移动到 x=50, y=200 坐标,按下鼠标左键,然后抬起鼠标左键
import pyautogui as pag
pag.mouseDown(x=50, y=200)
pag.mouseUp()
实际上是执行了点击鼠标左键的操作
3.5.2 鼠标右键按下/抬起
将鼠标移动到 x=50, y=200 坐标,按下鼠标右键,然后抬起鼠标右键
import pyautogui as pag
pag.mouseDown(x=50, y=200, button="right")
pag.mouseUp(button="right")
实际上是执行了点击鼠标右键的操作
注意:鼠标按下(左/右键),要用对应的鼠标抬起(左/右键)结束!
3.5.3 鼠标按下/抬起 + 拖动
将连续的鼠标点击拆分为 鼠标按住和抬起 两个步骤,中间结合 鼠标移动 可以实现很多功能。比如拖拽,刷抖音,画画,写字等
用拖动文件举例:
import pyautogui as pag
pag.mouseDown(x=50, y=200)
pag.move(0, 200, duration=1)
pag.mouseUp()
鼠标移动到 x=50, y=200 坐标按下鼠标左键,向下移动 200 像素,然后松开鼠标左键,成功实现文件拖动
3.6 鼠标滚动
通过调用 scroll() 函数并传递一个整数(正数向上滚动,负数向下滚动)来模拟滚动
import pyautogui as pag
pag.click(x=600, y=300)
# 正数向上滚动,负数向下滚动
pag.scroll(-200)
滚动之前先传递一个点击事件,是为了把鼠标焦点放在将要滚动的区域,保证滚动事件生效
3.7 鼠标拖动
import pyautogui as pag
# 鼠标移动到坐标(50, 200),持续 1 秒
pag.moveTo(x=50, y=200, duration=1)
# 鼠标左键拖动图片到坐标(300, 200),持续 1 秒
pag.dragTo(300, 200, 1, button="left")
跟前面 3.5.3 鼠标按下/抬起 + 拖动 章节的效果差不多,区别是这里使用了原生的拖动函数 dragTo
注意:
-
button可选值有:'left'、'middle'和'right' -
鼠标拖动除了
dragTo(),还有drag()函数,跟鼠标移动的moveTo()和move()一个意思
3.8 鼠标缓动/过渡函数
鼠标缓动函数用于美化鼠标的移动效果,鼠标移动时,它会默认以恒定速度沿直线直接移动至目标位置
pyautogui 提供了几个鼠标缓动函数,可以让鼠标移动的过程显得不那么机械化
import pyautogui as pag
# 开头慢,结尾快
# pag.moveTo(x=50, y=200, duration=3, tween=pag.easeInQuad)
# 开头快,结尾慢
# pag.moveTo(x=50, y=200, duration=3, tween=pag.easeOutQuad)
# 开头和结尾快,中间慢
# pag.moveTo(x=50, y=200, duration=3, tween=pag.easeInOutQuad)
# 像橡皮筋一样,晃晃悠悠的将鼠标弹射到目标坐标点
# pag.moveTo(x=50, y=200, duration=3, tween=pag.easeInBounce)
# 感觉跟 easeInBounce 差不多
pag.moveTo(x=50, y=200, duration=3, tween=pag.easeInElastic)
4. 键盘控制
4.1 键盘输入
通过调用 write() 函数输出指定内容
import pyautogui as pag
pag.click(x=600, y=300)
pag.write("Hello world!", interval=0.25)
interval:延迟时间,这里表示每个字符延迟 0.25 秒输入
注意:pyautogui 的 write() 函数不支持中文输入,可以用 剪切粘贴 来间接实现
提前将要输入的中文复制到剪切板,然后执行粘贴程序
import pyautogui as pag
pag.click(x=600, y=300)
pag.hotkey("ctrl", "v")
还可以安装一个三方库 pyperclip 来代替复制的功能,然后粘贴,实现中文输入
4.2 键盘按键
4.2.1 press() 特殊/功能按键
write() 函数只能按单个字符键,如果想按下 Shift 或 F1 键等功能按键,需要使用 press() 函数
import pyautogui as pag
pag.click(x=600, y=300)
# 常用功能按键
# Shift
pag.press("Shift")
# ctrl
pag.press("ctrl")
# alt
pag.press("alt")
# tab
pag.press("tab")
# f1
pag.press("f1")
# 回车
pag.press("enter")
# 退出
pag.press("esc")
# 删除
pag.press("delete")
presses 参数设置按键的次数,interval 参数设置按键的间隔时间
import pyautogui as pag
# 按 3 次 tab 键,每次间隔一秒
pag.press("tab", presses=3, interval=1)
4.2.2 keyDown + keyUp 控制按键的按下与抬起
keyDown 和 keyUp 键可手动控制按键的 按下 和 抬起
import pyautogui as pag
pag.click(x=600, y=300) # 先点击记事本让它获得焦点
# 按住 shift 键,同时按下左箭头键按三次
pag.keyDown("shift")
# interval 参数设置按键的间隔时间
pag.press("left", presses=3, interval=0.3)
pag.keyUp("shift")
注意:Num Lock(数字键盘)需要关闭(Num Lock 开启时,箭头键有时会被当成数字键盘,修饰键行为会乱)
4.2.3 hold () 保持按键状态
hold() 函数可以用作上下文管理器,用于更方便地保持按键状态,在 with 上下文块持续期间保持按下状态
import pyautogui as pag
pag.click(x=600, y=300) # 先点击记事本让它获得焦点
with pag.hold("shift"):
pag.press("left", presses=3)
这段代码等于上面的 keyDown + keyUp,同样注意按下 left 箭头键时,需要关闭 Num Lock(数字键盘)
4.2.4 hotkey () 快捷键/热键
hotkey () 函数用于实现键盘快捷键/热键,它按先后顺序按下,然后按相反顺序释放
比如执行 pag.hotkey("ctrl", "a"),等同于执行
pyautogui.keyDown('ctrl')
pyautogui.keyDown('a')
pyautogui.keyUp('ctrl')
pyautogui.keyUp('a')
常用组合键
import pyautogui as pag
# 全选
pag.hotkey("ctrl", "a")
# 复制
pag.hotkey("ctrl", "c")
# 粘贴
pag.hotkey("ctrl", "v")
# 保存
pag.hotkey("ctrl", "s")
# 粘贴后保存
pag.hotkey("ctrl", "v", "s")
interval 参数设置按键的间隔时间
import pyautogui as pag
pag.hotkey("ctrl", "v", "s", interval=1)
4.2.5 键盘按键的有效字符串
关于 press() 、 keyDown() 、 keyUp() 和 hotkey() 函数的有效字符串,请查看官方文档:pyautogui.readthedocs.io/en/latest/k…
5. 屏幕控制
5.1 屏幕截图
截图功能需要 Pillow 模块,在项目根目录执行命令安装 Pillow 库
uv add Pillow
这条命令会自动做三件事:
- 下载并安装最新版的 Pillow;
- 将 Pillow 添加到 pyproject.toml 的依赖列表中([project.dependencies]);
- 更新 uv.lock 文件以锁定版本
截图功能需要用到 screenshot() 函数:第一个参数写要保存截图的文件路径和文件名(不指定路径的话默认放在项目根目录),第二个参数(region)指定截图范围(不指定的话默认截全屏)
import pyautogui as pag
pag.screenshot("./img/test.png", region=(0, 0, 300, 300))
如动图所示,我在项目根目录下创建了一个 img 文件夹,将截图的图片命名为 test.png 并放入 img 文件夹,截图的范围是:从左坐标为 0、上坐标为 0 的坐标点开始,绘制 300 像素宽度、 300 像素高度的截图
5.2 图像识别与定位
5.2.1 读取并识别图像
因为所有的点击操作都基于坐标开始,在实际应用中,我们不可能每次都提前预见或者定义好坐标值,所以就需要通过识别预设的图片来获取坐标
将想要识别的图片提前截图保存到本地,然后读取这张图片,获取这张图片的像素坐标点,实现“图像定位”的作用,然后计算此图片的中心点坐标,并点击
import pyautogui as pag
btn7 = pag.locateOnScreen("./img/7.png")
print(btn7)
locateOnScreen() 函数共返回四个参数:left=593, top=1053, width=81, height=112
5.2.2 获取图像的中心坐标
返回匹配图像的中心坐标,有两种写法,可以自行计算获取
import pyautogui as pag
targetImage = pag.locateOnScreen("./img/test.png")
print("targetImage", targetImage)
x = targetImage.left + targetImage.width // 2
y = targetImage.top + targetImage.height // 2
print("x", x)
print("y", y)
也可以通过现成的 locateCenterOnScreen() API 直接读取图像并获取中心坐标
import pyautogui as pag
center = pag.locateCenterOnScreen("./img/test.png")
print("center", center)
5.2.3 识别图像并点击图像中心点
获取后将中心坐标传入鼠标点击函数,实现点击图像功能,常用于点击动态位置的按钮
import pyautogui as pag
center = pag.locateCenterOnScreen("./img/test.png")
print("center", center)
# 点击图像中心点
pag.click(x=center.x, y=center.y)
6. 消息框
import pyautogui as pag
pag.countdown(5)
# 警告框
# alert = pag.alert(text="掘金-闲云一鹤", title="警告框", button="OK")
# print("alert:", alert)
# 确认框
# confirm = pag.confirm(text="掘金-闲云一鹤", title="确认框", buttons=["OK", "Cancel"])
# print("confirm:", confirm)
# 输入框
# prompt = pag.prompt(text="掘金-闲云一鹤", title="输入框", default="555")
# print("prompt:", prompt)
# 密码框
password = pag.password(text="掘金-闲云一鹤", title="密码框", default="666", mask="*")
print("password:", password)
每个消息框函数都有返回值。图片中密码框点击 OK 的返回值是打印输入的密码值,点击 Cancel 的返回值是 None 。其他消息框函数的代码已提供,不再赘述,可自行尝试
7. PyAutoGUI 自动化实战案例
我这里只是举一些我能想到的使用 PyAutoGUI 自动化操作的案例,大家可以充分发挥,根据需求自行定制
7.1 鼠标轨迹记录与回放
7.1.1 轨迹记录
程序执行 3 秒后鼠标一旦移动 → 自动开始记录 → 连续 3 秒没有移动 → 自动停止并输出轨迹 → 保存为 JSON 文件
import json
import time
import pyautogui
trajectory = []
last_pos = pyautogui.position()
last_move_time = None
recording = False
print("3秒后启动程序:移动鼠标记录轨迹,3秒无操作停止记录。")
time.sleep(3)
while True:
current_pos = pyautogui.position()
if current_pos != last_pos:
if not recording:
print("开始记录...")
recording = True
trajectory.append(current_pos)
print(current_pos)
last_move_time = time.time()
last_pos = current_pos
if recording and last_move_time is not None:
if time.time() - last_move_time > 3:
print("3秒未移动,停止记录")
break
time.sleep(0.1)
# ===== 保存为 JSON =====
with open("trajectory.json", "w") as f:
json.dump(trajectory, f)
print("已保存到 trajectory.json")
7.1.2 轨迹回放
用 mouseDown,move,mouseUp 实现回放
import json
import pyautogui
# ===== 读取 JSON =====
with open("trajectory.json", "r") as f:
trajectory = json.load(f)
if not trajectory:
print("没有轨迹数据")
exit()
# 移动到起点
pyautogui.moveTo(trajectory[0][0], trajectory[0][1], duration=0.2)
# 按下鼠标
pyautogui.mouseDown()
# 按轨迹移动
for x, y in trajectory:
pyautogui.moveTo(x, y, duration=0.1) # 设置非常短的持续时间以实现平滑移动
# 松开鼠标
pyautogui.mouseUp()
print("回放完成")
7.2 游戏自动化
游戏脚本自动化是指通过编写脚本程序,模拟玩家的操作,实现游戏的自动化运行。常见的应用场景包括:
- 自动打怪:在角色扮演游戏中,自动寻找并击败怪物。
- 资源采集:在模拟经营游戏中,自动采集资源。
- 任务完成:自动完成各种任务,获取奖励。
注意:不要过于频繁地进行自动化操作,适当加入随机延迟,尽量模拟真实的用户操作动作,避免被识别为机器导致封号
7.2.1 咸鱼之王自动开箱子
宝箱周任务,自动开箱子。基础代码就两行:识别+点击
import pyautogui as pag
center = pag.locateCenterOnScreen("./img/kxz-again.png")
print("center", center)
pag.click(x=center.x, y=center.y, clicks=100, interval=5)
加上防检测:随机点击间隔时间为 1~2 秒,随机点击位置,点击持续时间,使操作更接近真实的人类
import random
import time
import pyautogui as pag
pag.countdown(5) # 给用户5秒钟的时间来切换到目标窗口
# 获取目标图片在屏幕上的中心坐标
center = pag.locateCenterOnScreen("./img/kxz-again.png")
print("center:", center)
# 安全判断
if center is None:
raise Exception("未找到目标图片")
# 点击100次
for i in range(100):
# 每次基于 center 重新计算随机坐标(±50像素)
x = center.x + random.randint(-50, 50)
y = center.y + random.randint(-50, 50)
pag.click(x=x, y=y, duration=0.08) # 点击时增加一个小的持续时间,使点击更自然
# 随机间隔 1~2 秒
interval = random.uniform(1, 2)
print(f"第{i + 1}次点击 -> ({x}, {y}), 间隔: {interval:.2f}s")
time.sleep(interval)
可以看到,每次点击的间隔时间以及位置都有少量偏移,使操作显得更像真人
7.2.2 自动玩打地鼠
核心逻辑:略
7.2.3 自动玩跳一跳
核心逻辑:略
7.2.4 自动玩数独/扫雷
核心逻辑:略
7.2.5 自动抢红包雨
核心逻辑:略
7.3 办公自动化
7.3.1 表单自动填写
通过复制粘贴组合键,结合图片识别,和Excel/数据库读取,实现批量填充 Excel 数据到网页表单功能
或者从PDF复制文字 → 粘贴到Excel
7.3.2 自动挂机刷网课
通过图像识别网课在线监测,自动播放课程视频
核心逻辑:locateCenterOnScreen() 图像识别函数获取中心坐标 + click() 鼠标点击
7.3.3 动态网页截图
定时刷新截取网页数据并保存,用于监控价格或库存变化
核心逻辑:screenshot() 函数截图
7.3.4 自动浏览网页,看小说
核心逻辑:scroll() 鼠标滚动函数
7.3.5 自动刷抖音
核心逻辑:dragTo() 鼠标拖动函数
7.3.6 给关注的用户列表自动点赞
核心逻辑:略
7.3.7 定时自动关机
倒计时结束,鼠标点击自动关机
核心逻辑:略
7.3.8 自动写字表白
自动新建并打开记事本,一字一字的蹦出来想说的话
核心逻辑:locateCenterOnScreen() 图像识别 + click() 鼠标点击打开记事本 + pag.hotkey("ctrl", "v") 组合键输出文字内容
7.3.9 防休眠摸鱼助手
每隔 60 秒微微抖动鼠标,让电脑不息屏,偷跑出去玩领导也不知道哈哈哈
8. 注意事项
8.1 异常处理机制
PyAutoGUI 提供多层次的安全保障,确保自动化过程可控
全局操作延迟:默认值为 0.1
pyautogui.PAUSE = 1.0 # 所有操作间增加1秒延迟
故障安全机制:快速将鼠标移动到主显示器四个角落中的任意一个,它会触发 pyautogui.FailSafeException 异常,从而终止程序;FAILSAFE 是默认开启的,可以通过设置 pyautogui.FAILSAFE = False 来禁用此保护。强烈建议不要禁用它。
pyautogui.FAILSAFE = True # 鼠标移至屏幕任意角落时触发程序终止
8.2 防检测
PyAutoGUI 模拟的操作过于 “机械”,部分软件 / 网站会检测到自动化,可通过以下方式简单规避(模拟人类操作特点):
-
设置
操作间隔:pyautogui.PAUSE=0.5-1秒,避免操作过快;随机延迟 -
鼠标
缓动移动:保留 duration(程序执行的时间)参数,让鼠标移动有平滑过程,而非瞬间移动 -
偶尔暂停:每执行 N 次操作,暂停 2-3 秒,模拟人类休息
-
偶尔点击空白区域,或者鼠标随机乱滑动两下
8.3 最佳实践
-
所有自动化操作前,加入预留时间(sleep(3)),方便手动切换到目标窗口
-
使用图像定位(locateCenterOnScreen()),替代固定坐标,提升程序兼容性
-
tkinter/PyQt:制作图形界面,让自动化程序更易用
-
加入随机延迟 / 随机操作间隔,模拟人类操作,避免被检测为自动化程序
-
全程使用异常捕获(try/except),避免单次操作失败导致程序崩溃
-
温馨提示:如果用于游戏自动化,避免参与游戏核心内容,例如实时对战游戏你用鼠标自动玩就大大的增加封号概率。像咸鱼之王之类的游戏,核心玩法是囤积材料的养成游戏,用鼠标帮忙开箱子之类的玩法,官方想必也不会在意,因为跟游戏的核心玩法不冲突。