PyAutoGUI详解3
第7章:高级功能与技巧
7.1 多显示器支持
7.1.1 显示器信息获取
import pyautogui
def monitor_info():
"""
显示器信息获取
"""
# 获取主显示器尺寸
screen_width, screen_height = pyautogui.size()
print(f"主显示器尺寸: {screen_width}x{screen_height}")
# 获取所有显示器信息
try:
import screeninfo
monitors = screeninfo.get_monitors()
print(f"\n检测到 {len(monitors)} 个显示器:")
for i, monitor in enumerate(monitors):
print(f" 显示器 {i+1}:")
print(f" 位置: ({monitor.x}, {monitor.y})")
print(f" 尺寸: {monitor.width}x{monitor.height}")
print(f" 主显示器: {monitor.is_primary}")
except ImportError:
print("\n未安装screeninfo库,无法获取多显示器信息")
print("请运行: pip install screeninfo")
# 检测鼠标位置
mouse_x, mouse_y = pyautogui.position()
print(f"\n当前鼠标位置: ({mouse_x}, {mouse_y})")
# 验证坐标范围
def is_valid_coordinate(x, y):
"""验证坐标是否有效"""
try:
# 尝试获取像素颜色
pyautogui.pixel(x, y)
return True
except Exception:
return False
# 测试坐标有效性
test_coords = [(0, 0), (screen_width-1, screen_height-1), (10000, 10000)]
print("\n坐标有效性测试:")
for x, y in test_coords:
valid = is_valid_coordinate(x, y)
print(f" 坐标 ({x}, {y}): {'有效' if valid else '无效'}")
7.1.2 跨显示器操作
import pyautogui
def cross_monitor_operations():
"""
跨显示器操作
"""
# 获取主显示器尺寸
screen_width, screen_height = pyautogui.size()
# 移动鼠标到主显示器中心
center_x = screen_width // 2
center_y = screen_height // 2
print(f"移动鼠标到主显示器中心: ({center_x}, {center_y})")
pyautogui.moveTo(center_x, center_y, duration=1.0)
# 假设第二显示器在主显示器右侧
second_monitor_x = screen_width + 500
second_monitor_y = center_y
print(f"移动鼠标到第二显示器: ({second_monitor_x}, {second_monitor_y})")
pyautogui.moveTo(second_monitor_x, second_monitor_y, duration=1.0)
# 在第二显示器上点击
print("在第二显示器上点击")
pyautogui.click()
# 在第二显示器上输入文本
print("在第二显示器上输入文本")
pyautogui.write("Hello from second monitor!")
pyautogui.press('enter')
# 跨显示器截图
def screenshot_multiple_monitors():
"""跨显示器截图"""
print("截取整个屏幕(包括所有显示器)")
screenshot = pyautogui.screenshot()
screenshot.save('full_screen.png')
print(f"截图尺寸: {screenshot.size}")
print("保存到 full_screen.png")
# 测试跨显示器截图
screenshot_multiple_monitors()
# 安全的跨显示器操作
def safe_cross_monitor_click(x, y):
"""
安全的跨显示器点击
Args:
x: x坐标
y: y坐标
"""
try:
# 先移动鼠标
pyautogui.moveTo(x, y, duration=0.5)
# 等待一小段时间
pyautogui.PAUSE = 0.2
# 执行点击
pyautogui.click()
print(f"成功点击坐标: ({x}, {y})")
except Exception as e:
print(f"点击失败: {e}")
# 测试安全点击
safe_cross_monitor_click(second_monitor_x, second_monitor_y)
7.2 安全机制与控制
7.2.1 FAILSAFE机制详解
import pyautogui
def failsafe_mechanism():
"""
FAILSAFE机制详解
"""
# 查看当前FAILSAFE设置
print(f"当前FAILSAFE设置: {pyautogui.FAILSAFE}")
# 启用FAILSAFE
pyautogui.FAILSAFE = True
print("已启用FAILSAFE")
# 注意:FAILSAFE_POINTS 和 FAILSAFE_DISTANCE 不是PyAutoGUI标准属性
# 以下展示如何自定义实现类似功能
# 自定义安全区域检查函数
def check_failsafe_area(x_threshold=50, y_threshold=50):
"""
检查鼠标是否在安全区域(屏幕左上角)
Args:
x_threshold: X轴安全阈值(像素)
y_threshold: Y轴安全阈值(像素)
Returns:
bool: 是否在安全区域内
"""
current_pos = pyautogui.position()
return current_pos[0] < x_threshold and current_pos[1] < y_threshold
# 测试自定义安全区域检查
print("\n测试自定义安全区域检查:")
print("将鼠标移动到屏幕左上角(0,0)附近将触发安全警告")
print("按Ctrl+C终止测试")
try:
# 无限循环移动鼠标
import time
x, y = 100, 100
direction = 1
while True:
x += direction * 5
if x > 500 or x < 100:
direction *= -1
pyautogui.moveTo(x, y, duration=0.1)
time.sleep(0.1)
except KeyboardInterrupt:
print("测试终止")
except pyautogui.FailSafeException:
print("FAILSAFE触发!")
# 禁用FAILSAFE(谨慎使用)
def disable_failsafe():
"""禁用FAILSAFE"""
pyautogui.FAILSAFE = False
print("\n已禁用FAILSAFE")
print("警告: 禁用FAILSAFE可能导致失控,建议仅在受控环境中使用")
# 重新启用FAILSAFE
def enable_failsafe():
"""启用FAILSAFE"""
pyautogui.FAILSAFE = True
print("已重新启用FAILSAFE")
# 测试禁用和启用
# disable_failsafe()
# enable_failsafe()
7.2.2 延迟控制与速度调节
import pyautogui
import time
def delay_control():
"""
延迟控制与速度调节
"""
# 查看当前PAUSE设置
print(f"当前PAUSE设置: {pyautogui.PAUSE}秒")
# 临时修改PAUSE
original_pause = pyautogui.PAUSE
pyautogui.PAUSE = 0.1
print(f"已将PAUSE设置为: {pyautogui.PAUSE}秒")
# 测试不同速度
def test_speed(duration, description):
"""
测试移动速度
Args:
duration: 移动持续时间
description: 测试描述
"""
print(f"\n{description} (duration={duration}秒):")
start_time = time.time()
pyautogui.moveTo(100, 100, duration=duration)
pyautogui.moveTo(500, 100, duration=duration)
pyautogui.moveTo(500, 300, duration=duration)
pyautogui.moveTo(100, 300, duration=duration)
pyautogui.moveTo(100, 100, duration=duration)
elapsed = time.time() - start_time
print(f" 实际耗时: {elapsed:.2f}秒")
# 测试不同速度
test_speed(0.1, "快速移动")
test_speed(0.5, "中等速度")
test_speed(1.0, "慢速移动")
# 恢复原始PAUSE
pyautogui.PAUSE = original_pause
print(f"\n已恢复PAUSE设置: {pyautogui.PAUSE}秒")
# 批量操作的速度控制
def batch_operations_with_speed_control():
"""带速度控制的批量操作"""
items = [f"item_{i}" for i in range(5)]
# 快速模式
print("\n快速模式:")
pyautogui.PAUSE = 0.05
start_time = time.time()
for item in items:
pyautogui.click(100, 100)
pyautogui.write(item)
pyautogui.press('enter')
elapsed = time.time() - start_time
print(f" 处理 {len(items)} 个项目耗时: {elapsed:.2f}秒")
# 慢速模式
print("\n慢速模式:")
pyautogui.PAUSE = 0.5
start_time = time.time()
for item in items:
pyautogui.click(100, 100)
pyautogui.write(item)
pyautogui.press('enter')
elapsed = time.time() - start_time
print(f" 处理 {len(items)} 个项目耗时: {elapsed:.2f}秒")
# 恢复默认
pyautogui.PAUSE = original_pause
# 测试批量操作速度
batch_operations_with_speed_control()
7.3 坐标系统与映射
7.3.1 屏幕坐标系统
import pyautogui
def coordinate_system():
"""
屏幕坐标系统
"""
# 获取屏幕尺寸
screen_width, screen_height = pyautogui.size()
print(f"屏幕尺寸: {screen_width}x{screen_height}")
# 计算中心点
center_x = screen_width // 2
center_y = screen_height // 2
print(f"屏幕中心: ({center_x}, {center_y})")
# 关键坐标点
key_points = {
'左上角': (0, 0),
'右上角': (screen_width - 1, 0),
'左下角': (0, screen_height - 1),
'右下角': (screen_width - 1, screen_height - 1),
'中心': (center_x, center_y)
}
print("\n关键坐标点:")
for name, (x, y) in key_points.items():
print(f" {name}: ({x}, {y})")
# 坐标转换
def relative_to_absolute(relative_x, relative_y):
"""
相对坐标转绝对坐标
Args:
relative_x: 相对x坐标 (0.0-1.0)
relative_y: 相对y坐标 (0.0-1.0)
Returns:
tuple: 绝对坐标
"""
absolute_x = int(screen_width * relative_x)
absolute_y = int(screen_height * relative_y)
return (absolute_x, absolute_y)
# 测试坐标转换
relative_coords = [(0, 0), (0.5, 0.5), (1.0, 1.0), (0.25, 0.75)]
print("\n相对坐标转绝对坐标:")
for rel_x, rel_y in relative_coords:
abs_x, abs_y = relative_to_absolute(rel_x, rel_y)
print(f" 相对 ({rel_x:.2f}, {rel_y:.2f}) -> 绝对 ({abs_x}, {abs_y})")
# 安全坐标检查
def safe_coordinate(x, y):
"""
确保坐标在安全范围内
Args:
x: x坐标
y: y坐标
Returns:
tuple: 安全的坐标
"""
safe_x = max(0, min(x, screen_width - 1))
safe_y = max(0, min(y, screen_height - 1))
return (safe_x, safe_y)
# 测试安全坐标
test_coords = [(-100, -100), (screen_width + 100, screen_height + 100), (center_x, center_y)]
print("\n安全坐标检查:")
for x, y in test_coords:
safe_x, safe_y = safe_coordinate(x, y)
print(f" 原始 ({x}, {y}) -> 安全 ({safe_x}, {safe_y})")
7.3.2 窗口坐标映射
import pyautogui
def window_coordinate_mapping():
"""
窗口坐标映射
"""
# 获取活动窗口位置(需要pygetwindow)
try:
import pygetwindow as gw
# 获取当前活动窗口
active_window = gw.getActiveWindow()
if active_window:
print(f"活动窗口: {active_window.title}")
print(f"窗口位置: ({active_window.left}, {active_window.top})")
print(f"窗口尺寸: {active_window.width}x{active_window.height}")
# 窗口内坐标转换
def window_to_screen(window, window_x, window_y):
"""
窗口内坐标转屏幕坐标
Args:
window: 窗口对象
window_x: 窗口内x坐标
window_y: 窗口内y坐标
Returns:
tuple: 屏幕坐标
"""
screen_x = window.left + window_x
screen_y = window.top + window_y
return (screen_x, screen_y)
# 测试窗口坐标转换
window_center_x = active_window.width // 2
window_center_y = active_window.height // 2
screen_x, screen_y = window_to_screen(active_window, window_center_x, window_center_y)
print(f"\n窗口中心 -> 屏幕坐标:")
print(f" 窗口内: ({window_center_x}, {window_center_y})")
print(f" 屏幕: ({screen_x}, {screen_y})")
# 点击窗口中心
print("点击窗口中心")
pyautogui.click(screen_x, screen_y)
else:
print("未找到活动窗口")
except ImportError:
print("未安装pygetwindow库")
print("请运行: pip install pygetwindow")
# 模拟窗口坐标映射
def simulate_window_mapping(window_left, window_top, window_width, window_height):
"""
模拟窗口坐标映射
Args:
window_left: 窗口左边界
window_top: 窗口上边界
window_width: 窗口宽度
window_height: 窗口高度
"""
print("\n模拟窗口坐标映射:")
print(f"窗口位置: ({window_left}, {window_top})")
print(f"窗口尺寸: {window_width}x{window_height}")
# 计算窗口内关键点
points = [
('左上角', 0, 0),
('右上角', window_width, 0),
('左下角', 0, window_height),
('右下角', window_width, window_height),
('中心', window_width // 2, window_height // 2)
]
print("\n窗口内坐标 -> 屏幕坐标:")
for name, wx, wy in points:
sx = window_left + wx
sy = window_top + wy
print(f" {name}: 窗口({wx}, {wy}) -> 屏幕({sx}, {sy})")
# 测试模拟窗口映射
simulate_window_mapping(100, 100, 800, 600)
7.4 高级控制技巧
7.4.1 上下文管理与资源释放
import pyautogui
import contextlib
def context_management():
"""
上下文管理与资源释放
"""
# 临时修改设置的上下文管理器
@contextlib.contextmanager
def temporary_settings(**kwargs):
"""
临时修改PyAutoGUI设置
Args:
**kwargs: 要临时修改的设置
"""
# 保存原始设置
original_settings = {}
for key, value in kwargs.items():
if hasattr(pyautogui, key):
original_settings[key] = getattr(pyautogui, key)
setattr(pyautogui, key, value)
try:
yield
finally:
# 恢复原始设置
for key, value in original_settings.items():
setattr(pyautogui, key, value)
# 测试上下文管理器
print(f"原始PAUSE: {pyautogui.PAUSE}")
print(f"原始FAILSAFE: {pyautogui.FAILSAFE}")
with temporary_settings(PAUSE=0.01, FAILSAFE=False):
print(f"临时PAUSE: {pyautogui.PAUSE}")
print(f"临时FAILSAFE: {pyautogui.FAILSAFE}")
# 执行快速操作
pyautogui.moveTo(100, 100, duration=0.1)
pyautogui.click()
print(f"恢复后PAUSE: {pyautogui.PAUSE}")
print(f"恢复后FAILSAFE: {pyautogui.FAILSAFE}")
# 资源管理
def safe_operation():
"""
安全的操作包装
"""
try:
# 执行操作
pyautogui.moveTo(100, 100)
pyautogui.click()
pyautogui.write("Test")
return True
except Exception as e:
print(f"操作失败: {e}")
return False
finally:
# 确保资源释放
pass
# 测试安全操作
success = safe_operation()
print(f"操作结果: {'成功' if success else '失败'}")
# 批量操作的上下文管理
def batch_operations(items):
"""
批量操作
Args:
items: 操作项列表
"""
with temporary_settings(PAUSE=0.05):
for i, item in enumerate(items):
print(f"处理项目 {i+1}/{len(items)}")
pyautogui.click(100, 100 + i * 20)
pyautogui.write(item)
pyautogui.press('enter')
# 测试批量操作
test_items = ["item1", "item2", "item3"]
batch_operations(test_items)
7.4.2 事件驱动操作
import pyautogui
import time
import threading
def event_driven_operations():
"""
事件驱动操作
"""
# 事件类
class PyAutoGUIEvent:
"""PyAutoGUI事件类"""
def __init__(self):
self._events = {}
def on(self, event_name, callback):
"""
注册事件回调
Args:
event_name: 事件名称
callback: 回调函数
"""
if event_name not in self._events:
self._events[event_name] = []
self._events[event_name].append(callback)
def emit(self, event_name, *args, **kwargs):
"""
触发事件
Args:
event_name: 事件名称
*args: 位置参数
**kwargs: 关键字参数
"""
if event_name in self._events:
for callback in self._events[event_name]:
try:
callback(*args, **kwargs)
except Exception as e:
print(f"事件处理失败: {e}")
# 创建事件管理器
events = PyAutoGUIEvent()
# 注册事件
def on_click(x, y):
print(f"点击事件: ({x}, {y})")
def on_move(x, y):
print(f"移动事件: ({x}, {y})")
events.on('click', on_click)
events.on('move', on_move)
# 模拟事件触发
print("模拟事件触发:")
events.emit('move', 100, 100)
events.emit('click', 100, 100)
# 监听鼠标位置变化
def monitor_mouse_position(interval=0.5, duration=5):
"""
监听鼠标位置变化
Args:
interval: 检查间隔
duration: 监听时长
"""
print(f"\n开始监听鼠标位置变化({duration}秒):")
start_time = time.time()
last_position = pyautogui.position()
while time.time() - start_time < duration:
current_position = pyautogui.position()
if current_position != last_position:
events.emit('move', *current_position)
last_position = current_position
time.sleep(interval)
print("监听结束")
# 测试鼠标位置监听
monitor_mouse_position()
# 异步操作
def async_operation():
"""
异步操作
"""
def long_operation():
"""长时间操作"""
print("开始长时间操作...")
time.sleep(3)
print("长时间操作完成")
events.emit('operation_complete', 'success')
# 启动异步线程
thread = threading.Thread(target=long_operation)
thread.daemon = True
thread.start()
# 主线程继续执行
print("主线程继续执行")
for i in range(5):
print(f"主线程工作 {i+1}/5")
time.sleep(0.5)
# 注册操作完成事件
def on_operation_complete(status):
print(f"操作完成,状态: {status}")
events.on('operation_complete', on_operation_complete)
# 测试异步操作
async_operation()
7.4.3 条件执行与智能判断
import pyautogui
import time
def conditional_execution():
"""
条件执行与智能判断
"""
# 等待条件满足
def wait_for_condition(condition, timeout=10, interval=0.5):
"""
等待条件满足
Args:
condition: 条件函数(返回bool)
timeout: 超时时间
interval: 检查间隔
Returns:
bool: 条件是否满足
"""
start_time = time.time()
while time.time() - start_time < timeout:
if condition():
return True
time.sleep(interval)
return False
# 示例条件:鼠标在特定区域
def mouse_in_region(x1, y1, x2, y2):
"""
检查鼠标是否在指定区域
Args:
x1, y1: 区域左上角
x2, y2: 区域右下角
Returns:
bool: 是否在区域内
"""
mouse_x, mouse_y = pyautogui.position()
return x1 <= mouse_x <= x2 and y1 <= mouse_y <= y2
# 测试条件等待
print("请将鼠标移动到区域 (100, 100) 到 (300, 300) 内")
success = wait_for_condition(lambda: mouse_in_region(100, 100, 300, 300), timeout=10)
print(f"条件满足: {success}")
# 智能重试
def smart_retry(operation, max_retries=3, delay=1):
"""
智能重试
Args:
operation: 操作函数
max_retries: 最大重试次数
delay: 重试间隔
Returns:
操作结果
"""
for attempt in range(max_retries):
try:
result = operation()
return result
except Exception as e:
print(f"尝试 {attempt+1}/{max_retries} 失败: {e}")
if attempt < max_retries - 1:
time.sleep(delay)
else:
raise
# 测试智能重试
def flaky_operation():
"""不稳定的操作"""
import random
if random.random() < 0.7:
raise Exception("随机失败")
return "成功"
try:
result = smart_retry(flaky_operation, max_retries=5)
print(f"操作结果: {result}")
except Exception as e:
print(f"所有尝试都失败: {e}")
# 条件分支
def conditional_branch():
"""
条件分支执行
"""
# 检查屏幕尺寸
screen_width, screen_height = pyautogui.size()
if screen_width > 1920:
print("大屏幕模式")
# 大屏幕操作
pyautogui.moveTo(screen_width // 2, screen_height // 2)
elif screen_width > 1366:
print("中等屏幕模式")
# 中等屏幕操作
pyautogui.moveTo(screen_width // 2, screen_height // 2)
else:
print("小屏幕模式")
# 小屏幕操作
pyautogui.moveTo(screen_width // 2, screen_height // 2)
# 测试条件分支
conditional_branch()
7.5 高级应用技巧
7.5.1 模拟复杂用户操作
import pyautogui
import time
def complex_user_operations():
"""
模拟复杂用户操作
"""
# 模拟用户登录
def simulate_login(username, password):
"""
模拟用户登录
Args:
username: 用户名
password: 密码
"""
print("开始模拟登录...")
# 打开登录窗口(假设已打开)
# pyautogui.hotkey('win', 'r')
# pyautogui.write('notepad')
# pyautogui.press('enter')
# 输入用户名
print("输入用户名")
pyautogui.write(username)
pyautogui.press('tab')
# 输入密码
print("输入密码")
pyautogui.write(password)
pyautogui.press('enter')
print("登录完成")
# 测试登录模拟
# simulate_login('testuser', 'password123')
# 模拟文件操作
def simulate_file_operation():
"""
模拟文件操作
"""
print("开始模拟文件操作...")
# 打开文件浏览器
pyautogui.hotkey('win', 'e')
time.sleep(1)
# 导航到桌面
pyautogui.write('Desktop')
pyautogui.press('enter')
time.sleep(1)
# 创建新文件夹
pyautogui.hotkey('ctrl', 'shift', 'n')
time.sleep(0.5)
pyautogui.write('Test Folder')
pyautogui.press('enter')
# 双击打开文件夹
pyautogui.doubleClick(100, 100) # 假设文件夹在(100, 100)
time.sleep(1)
# 关闭窗口
pyautogui.hotkey('alt', 'f4')
print("文件操作完成")
# 测试文件操作
# simulate_file_operation()
# 模拟网页操作
def simulate_web_browsing():
"""
模拟网页浏览
"""
print("开始模拟网页浏览...")
# 打开浏览器
pyautogui.hotkey('win', 'r')
pyautogui.write('chrome')
pyautogui.press('enter')
time.sleep(2)
# 访问网站
pyautogui.write('https://www.baidu.com')
pyautogui.press('enter')
time.sleep(3)
# 搜索
pyautogui.write('PyAutoGUI')
pyautogui.press('enter')
time.sleep(2)
# 点击链接
# 注意:实际坐标需要根据屏幕调整
# pyautogui.click(500, 300)
# 关闭浏览器
pyautogui.hotkey('alt', 'f4')
print("网页浏览完成")
# 测试网页浏览
# simulate_web_browsing()
7.5.2 自动化工作流
import pyautogui
import time
def automation_workflow():
"""
自动化工作流
"""
# 工作流类
class Workflow:
"""自动化工作流类"""
def __init__(self):
self.steps = []
def add_step(self, name, action, *args, **kwargs):
"""
添加工作流步骤
Args:
name: 步骤名称
action: 操作函数
*args: 位置参数
**kwargs: 关键字参数
"""
self.steps.append({
'name': name,
'action': action,
'args': args,
'kwargs': kwargs
})
def run(self):
"""
运行工作流
"""
print(f"开始执行工作流,共 {len(self.steps)} 个步骤")
for i, step in enumerate(self.steps, 1):
print(f"执行步骤 {i}/{len(self.steps)}: {step['name']}")
try:
step['action'](*step['args'], **step['kwargs'])
print(f"步骤 {i} 完成")
except Exception as e:
print(f"步骤 {i} 失败: {e}")
# 可以添加错误处理逻辑
time.sleep(1) # 步骤间延迟
print("工作流执行完成")
# 创建工作流
workflow = Workflow()
# 定义步骤函数
def open_application(app_name):
"""打开应用程序"""
pyautogui.hotkey('win', 'r')
pyautogui.write(app_name)
pyautogui.press('enter')
time.sleep(2)
def enter_text(text):
"""输入文本"""
pyautogui.write(text)
def click_button(x, y):
"""点击按钮"""
pyautogui.click(x, y)
def close_application():
"""关闭应用程序"""
pyautogui.hotkey('alt', 'f4')
# 添加步骤
workflow.add_step('打开记事本', open_application, 'notepad')
workflow.add_step('输入标题', enter_text, 'PyAutoGUI 自动化测试\n')
workflow.add_step('输入内容', enter_text, '这是一个自动化测试示例\n使用工作流管理多个操作步骤')
workflow.add_step('点击编辑菜单', click_button, 50, 20) # 假设坐标
workflow.add_step('关闭记事本', close_application)
# 运行工作流
# workflow.run()
# 条件工作流
def conditional_workflow():
"""
条件工作流
"""
print("开始条件工作流")
# 检查屏幕尺寸
screen_width, screen_height = pyautogui.size()
if screen_width >= 1920:
print("高分辨率屏幕,执行A工作流")
# 执行A工作流
else:
print("低分辨率屏幕,执行B工作流")
# 执行B工作流
# 测试条件工作流
conditional_workflow()
7.5.3 性能优化技巧
import pyautogui
import time
def performance_optimization():
"""
性能优化技巧
"""
# 批量操作优化
def batch_optimization():
"""
批量操作优化
"""
items = list(range(100))
# 传统方法
print("传统方法:")
start_time = time.time()
for item in items:
pyautogui.moveTo(100, 100)
pyautogui.click()
pyautogui.write(str(item))
pyautogui.press('enter')
elapsed = time.time() - start_time
print(f" 处理 {len(items)} 个项目耗时: {elapsed:.2f}秒")
# 优化方法
print("\n优化方法:")
start_time = time.time()
original_pause = pyautogui.PAUSE
pyautogui.PAUSE = 0.01
try:
for item in items:
pyautogui.moveTo(100, 100)
pyautogui.click()
pyautogui.write(str(item))
pyautogui.press('enter')
finally:
pyautogui.PAUSE = original_pause
elapsed = time.time() - start_time
print(f" 处理 {len(items)} 个项目耗时: {elapsed:.2f}秒")
# 测试批量优化
# batch_optimization()
# 坐标缓存
def coordinate_caching():
"""
坐标缓存
"""
# 缓存常用坐标
coordinates = {
'button_ok': (100, 100),
'button_cancel': (200, 100),
'input_field': (150, 150)
}
print("使用坐标缓存:")
start_time = time.time()
for _ in range(100):
# 从缓存获取坐标
pyautogui.click(coordinates['button_ok'])
pyautogui.click(coordinates['input_field'])
pyautogui.click(coordinates['button_cancel'])
elapsed = time.time() - start_time
print(f" 执行100次操作耗时: {elapsed:.2f}秒")
# 测试坐标缓存
coordinate_caching()
# 并行操作
def parallel_operations():
"""
并行操作
"""
import threading
def task1():
"""任务1"""
for i in range(10):
pyautogui.moveTo(100, 100 + i * 10)
time.sleep(0.1)
def task2():
"""任务2"""
for i in range(10):
pyautogui.moveTo(200, 100 + i * 10)
time.sleep(0.1)
print("\n并行操作:")
start_time = time.time()
# 创建线程
thread1 = threading.Thread(target=task1)
thread2 = threading.Thread(target=task2)
# 启动线程
thread1.start()
thread2.start()
# 等待完成
thread1.join()
thread2.join()
elapsed = time.time() - start_time
print(f" 并行执行耗时: {elapsed:.2f}秒")
# 测试并行操作
parallel_operations()
# 减少屏幕交互
def reduce_screen_interactions():
"""
减少屏幕交互
"""
print("\n减少屏幕交互:")
# 直接操作vs屏幕操作
start_time = time.time()
# 直接操作(如果可能)
# 这里只是示例,实际应用中需要根据具体情况
print(" 执行直接操作")
elapsed = time.time() - start_time
print(f" 直接操作耗时: {elapsed:.2f}秒")
# 屏幕操作
start_time = time.time()
pyautogui.moveTo(100, 100)
pyautogui.click()
pyautogui.write("test")
pyautogui.press('enter')
elapsed = time.time() - start_time
print(f" 屏幕操作耗时: {elapsed:.2f}秒")
# 测试减少屏幕交互
reduce_screen_interactions()
第8章 生产环境最佳实践
8.1 异常处理与容错机制
在生产环境中,异常处理是保证自动化脚本稳定运行的关键。
8.1.1 基本异常处理
import pyautogui
import traceback
def safe_automation():
"""
安全的自动化操作,包含异常处理
"""
try:
# 执行自动化操作
pyautogui.moveTo(100, 100, duration=0.5)
pyautogui.click()
pyautogui.write('Test', interval=0.1)
except pyautogui.FailSafeException:
print("检测到FAILSAFE信号,脚本已停止")
return False
except pyautogui.ImageNotFoundException:
print("未找到目标图像")
return False
except Exception as e:
print(f"发生异常: {e}")
print(traceback.format_exc())
return False
else:
print("操作执行成功")
return True
# 调用示例
if __name__ == "__main__":
success = safe_automation()
if not success:
print("自动化操作失败,需要人工干预")
8.1.2 高级异常处理策略
import pyautogui
import time
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('automation.log'),
logging.StreamHandler()
]
)
def retry_operation(max_attempts=3, delay=1):
"""
带重试机制的操作装饰器
Args:
max_attempts: 最大尝试次数
delay: 重试间隔(秒)
"""
def decorator(func):
def wrapper(*args, **kwargs):
attempts = 0
while attempts < max_attempts:
try:
result = func(*args, **kwargs)
return result
except Exception as e:
attempts += 1
logging.warning(f"操作失败 (尝试 {attempts}/{max_attempts}): {e}")
if attempts < max_attempts:
time.sleep(delay)
else:
logging.error(f"操作最终失败: {e}")
raise
return wrapper
return decorator
@retry_operation(max_attempts=3, delay=2)
def locate_and_click(image_path, confidence=0.8):
"""
定位并点击图像
"""
logging.info(f"尝试定位图像: {image_path}")
position = pyautogui.locateCenterOnScreen(
image_path,
confidence=confidence
)
if position is None:
raise pyautogui.ImageNotFoundException(f"未找到图像: {image_path}")
pyautogui.click(position)
logging.info(f"点击位置: {position}")
return position
# 调用示例
if __name__ == "__main__":
try:
locate_and_click('button.png')
except Exception as e:
logging.error(f"自动化流程失败: {e}")
8.2 日志记录与监控
8.2.1 结构化日志
import pyautogui
import logging
import json
from datetime import datetime
# 配置结构化日志
class JsonFormatter(logging.Formatter):
def format(self, record):
log_record = {
'timestamp': datetime.utcnow().isoformat(),
'level': record.levelname,
'message': record.getMessage(),
'module': record.module,
'function': record.funcName,
'line': record.lineno
}
return json.dumps(log_record)
# 设置日志
logger = logging.getLogger('pyautogui_automation')
logger.setLevel(logging.INFO)
# 添加文件处理器
file_handler = logging.FileHandler('automation.log')
file_handler.setFormatter(JsonFormatter())
logger.addHandler(file_handler)
# 添加控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s'))
logger.addHandler(console_handler)
def automated_workflow():
"""
自动化工作流
"""
logger.info("开始自动化工作流")
try:
# 步骤1:启动应用
logger.info("启动应用")
pyautogui.press('win')
pyautogui.write('notepad', interval=0.1)
pyautogui.press('enter')
time.sleep(1)
# 步骤2:输入文本
logger.info("输入示例文本")
pyautogui.write('Hello, PyAutoGUI!', interval=0.05)
# 步骤3:保存文件
logger.info("保存文件")
pyautogui.hotkey('ctrl', 's')
time.sleep(0.5)
pyautogui.write('test.txt', interval=0.05)
pyautogui.press('enter')
logger.info("工作流执行成功")
return True
except Exception as e:
logger.error(f"工作流执行失败: {str(e)}")
return False
if __name__ == "__main__":
automated_workflow()
8.2.2 监控与告警
import pyautogui
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
class AutomationMonitor:
"""
自动化监控类
"""
def __init__(self, alert_email=None):
self.alert_email = alert_email
self.start_time = None
self.end_time = None
def start(self):
"""开始监控"""
self.start_time = time.time()
print(f"监控开始: {time.strftime('%Y-%m-%d %H:%M:%S')}")
def end(self):
"""结束监控"""
self.end_time = time.time()
duration = self.end_time - self.start_time
print(f"监控结束: {time.strftime('%Y-%m-%d %H:%M:%S')}")
print(f"执行时间: {duration:.2f} 秒")
def send_alert(self, subject, message):
"""发送告警邮件"""
if not self.alert_email:
return
try:
# 邮件配置
sender = "automation@example.com"
password = "your_password" # 实际使用时应从环境变量获取
smtp_server = "smtp.example.com"
smtp_port = 587
# 创建邮件
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = self.alert_email
msg['Subject'] = subject
msg.attach(MIMEText(message, 'plain'))
# 发送邮件
with smtplib.SMTP(smtp_server, smtp_port) as server:
server.starttls()
server.login(sender, password)
server.send_message(msg)
print(f"告警邮件已发送到 {self.alert_email}")
except Exception as e:
print(f"发送告警邮件失败: {e}")
def critical_operation():
"""
关键操作
"""
monitor = AutomationMonitor(alert_email="admin@example.com")
monitor.start()
try:
# 执行关键操作
pyautogui.moveTo(100, 100, duration=0.5)
pyautogui.click()
# ... 其他操作 ...
monitor.end()
print("关键操作执行成功")
except Exception as e:
monitor.end()
error_msg = f"关键操作执行失败: {str(e)}"
print(error_msg)
monitor.send_alert("自动化操作失败", error_msg)
if __name__ == "__main__":
critical_operation()
8.3 性能优化策略
8.3.1 执行速度优化
import pyautogui
import time
import cProfile
def optimize_performance():
"""
性能优化示例
"""
# 1. 减少延迟
original_pause = pyautogui.PAUSE
pyautogui.PAUSE = 0.01 # 减少默认延迟
try:
# 2. 批量操作
start_time = time.time()
# 优化前:逐个点击
print("优化前 - 逐个点击:")
for i in range(10):
pyautogui.click(100 + i*20, 100)
time1 = time.time() - start_time
print(f"耗时: {time1:.3f}秒")
# 优化后:直接移动+点击
start_time = time.time()
print("\n优化后 - 直接移动+点击:")
for i in range(10):
x, y = 100 + i*20, 100
pyautogui.moveTo(x, y, duration=0.05)
pyautogui.click()
time2 = time.time() - start_time
print(f"耗时: {time2:.3f}秒")
print(f"性能提升: {((time1 - time2) / time1 * 100):.1f}%")
finally:
# 恢复默认设置
pyautogui.PAUSE = original_pause
def profile_automation():
"""
性能分析
"""
def test_workflow():
for _ in range(5):
pyautogui.moveTo(100, 100, duration=0.1)
pyautogui.click()
pyautogui.write('test', interval=0.05)
pyautogui.press('enter')
print("性能分析:")
cProfile.run('test_workflow()')
if __name__ == "__main__":
optimize_performance()
print("\n" + "="*50 + "\n")
profile_automation()
8.3.2 内存优化
import pyautogui
import gc
import psutil
import os
def memory_optimization():
"""
内存优化示例
"""
def get_memory_usage():
"""获取当前内存使用情况"""
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024 # MB
print(f"初始内存使用: {get_memory_usage():.2f} MB")
# 模拟内存密集操作
screenshots = []
for i in range(10):
screenshot = pyautogui.screenshot()
screenshots.append(screenshot)
print(f"截图 {i+1} 后内存使用: {get_memory_usage():.2f} MB")
# 释放内存
print("\n释放内存:")
del screenshots
gc.collect()
print(f"释放后内存使用: {get_memory_usage():.2f} MB")
def efficient_screenshot():
"""
高效截图方法
"""
# 1. 只截取需要的区域
region = (0, 0, 800, 600)
print("截取指定区域:")
screenshot = pyautogui.screenshot(region=region)
print(f"区域截图大小: {screenshot.size}")
# 2. 直接保存到文件,避免内存中存储
print("\n直接保存到文件:")
pyautogui.screenshot('region.png', region=region)
print("截图已保存到 region.png")
if __name__ == "__main__":
memory_optimization()
print("\n" + "="*50 + "\n")
efficient_screenshot()
8.4 跨平台兼容性
8.4.1 平台检测与适配
import pyautogui
import platform
import sys
def platform_specific_operations():
"""
平台特定操作
"""
current_platform = platform.system()
print(f"当前平台: {current_platform}")
if current_platform == 'Windows':
# Windows 特定操作
print("执行 Windows 特定操作")
# 打开开始菜单
pyautogui.press('win')
time.sleep(0.5)
pyautogui.write('notepad', interval=0.1)
pyautogui.press('enter')
elif current_platform == 'Darwin': # macOS
print("执行 macOS 特定操作")
# 打开 Spotlight
pyautogui.hotkey('command', 'space')
time.sleep(0.5)
pyautogui.write('textedit', interval=0.1)
pyautogui.press('enter')
elif current_platform == 'Linux':
print("执行 Linux 特定操作")
# 打开应用启动器 (Ubuntu Unity)
pyautogui.hotkey('super')
time.sleep(0.5)
pyautogui.write('gedit', interval=0.1)
pyautogui.press('enter')
else:
print(f"未知平台: {current_platform}")
def cross_platform_coordinates():
"""
跨平台坐标处理
"""
# 获取屏幕尺寸
screen_width, screen_height = pyautogui.size()
print(f"屏幕尺寸: {screen_width} x {screen_height}")
# 使用相对坐标
relative_positions = {
'center': (0.5, 0.5),
'top_left': (0.1, 0.1),
'bottom_right': (0.9, 0.9)
}
print("相对坐标转换为绝对坐标:")
for name, (rel_x, rel_y) in relative_positions.items():
abs_x = int(screen_width * rel_x)
abs_y = int(screen_height * rel_y)
print(f"{name}: ({abs_x}, {abs_y})")
# 移动到该位置
pyautogui.moveTo(abs_x, abs_y, duration=0.5)
time.sleep(0.2)
if __name__ == "__main__":
platform_specific_operations()
print("\n" + "="*50 + "\n")
cross_platform_coordinates()
8.4.2 键盘布局适配
import pyautogui
import platform
def keyboard_layout_adapter():
"""
键盘布局适配
"""
current_platform = platform.system()
# 平台特定的键盘操作
key_mappings = {
'Windows': {
'copy': ['ctrl', 'c'],
'paste': ['ctrl', 'v'],
'save': ['ctrl', 's']
},
'Darwin': {
'copy': ['command', 'c'],
'paste': ['command', 'v'],
'save': ['command', 's']
},
'Linux': {
'copy': ['ctrl', 'c'],
'paste': ['ctrl', 'v'],
'save': ['ctrl', 's']
}
}
# 获取当前平台的按键映射
platform_mappings = key_mappings.get(current_platform, key_mappings['Linux'])
print(f"当前平台: {current_platform}")
print("按键映射:")
for action, keys in platform_mappings.items():
print(f"{action}: {'+'.join(keys)}")
# 示例:执行复制操作
print("\n执行复制操作:")
pyautogui.hotkey(*platform_mappings['copy'])
print("复制操作执行完成")
def unicode_compatibility():
"""
Unicode 兼容性处理
"""
# 测试 Unicode 输入
test_texts = [
"Hello World",
"你好,世界",
"こんにちは世界",
"안녕하세요 세계"
]
print("测试 Unicode 输入:")
for text in test_texts:
try:
pyautogui.write(text, interval=0.1)
pyautogui.press('enter')
print(f"成功输入: {text}")
except Exception as e:
print(f"输入失败 {text}: {e}")
time.sleep(0.5)
if __name__ == "__main__":
keyboard_layout_adapter()
print("\n" + "="*50 + "\n")
unicode_compatibility()
8.5 CI/CD 集成
8.5.1 自动化测试集成
# .github/workflows/pyautogui-test.yml
"""
name: PyAutoGUI Automation Test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *' # 每天执行
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install pyautogui opencv-python
# 安装 Xvfb 用于无头测试
sudo apt-get update
sudo apt-get install -y xvfb
- name: Run tests with Xvfb
run: |
Xvfb :99 -screen 0 1920x1080x24 &
export DISPLAY=:99
python test_automation.py
"""
# test_automation.py
import pyautogui
import time
import unittest
class TestAutomation(unittest.TestCase):
"""
自动化测试用例
"""
def setUp(self):
"""测试前准备"""
pyautogui.PAUSE = 0.1
pyautogui.FAILSAFE = False
def test_basic_operations(self):
"""测试基本操作"""
# 测试鼠标移动
pyautogui.moveTo(100, 100, duration=0.5)
self.assertAlmostEqual(pyautogui.position()[0], 100, delta=5)
self.assertAlmostEqual(pyautogui.position()[1], 100, delta=5)
# 测试点击
pyautogui.click()
# 测试键盘输入
pyautogui.write('test', interval=0.05)
def test_screen_size(self):
"""测试屏幕尺寸获取"""
width, height = pyautogui.size()
self.assertGreater(width, 0)
self.assertGreater(height, 0)
def tearDown(self):
"""测试后清理"""
pass
if __name__ == '__main__':
unittest.main()
8.5.2 持续集成最佳实践
import pyautogui
import os
import sys
import logging
from datetime import datetime
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename=f'ci_automation_{datetime.now().strftime("%Y%m%d_%H%M%S")}.log'
)
def ci_automation_workflow():
"""
CI 环境下的自动化工作流
"""
try:
logging.info("开始 CI 自动化工作流")
# 1. 环境检查
logging.info("检查环境")
screen_width, screen_height = pyautogui.size()
logging.info(f"屏幕尺寸: {screen_width} x {screen_height}")
# 2. 执行自动化任务
logging.info("执行自动化任务")
# 示例:打开浏览器
if sys.platform == 'win32':
os.system('start chrome')
elif sys.platform == 'darwin':
os.system('open -a "Google Chrome"')
else:
os.system('google-chrome &')
time.sleep(3) # 等待浏览器启动
# 3. 执行操作
pyautogui.write('https://www.google.com', interval=0.05)
pyautogui.press('enter')
time.sleep(2)
# 4. 验证结果
logging.info("验证操作结果")
# 这里可以添加图像识别验证
logging.info("CI 自动化工作流执行成功")
return True
except Exception as e:
logging.error(f"CI 自动化工作流失败: {str(e)}")
return False
if __name__ == "__main__":
success = ci_automation_workflow()
sys.exit(0 if success else 1)
8.6 安全考虑
8.6.1 安全最佳实践
import pyautogui
import os
import getpass
import cryptography
from cryptography.fernet import Fernet
def secure_credentials():
"""
安全处理凭证
安全警告:
1. 以下代码中的用户名和密码仅为演示用途
2. 生产环境中绝不要硬编码敏感信息
3. 建议使用环境变量、配置文件或密钥管理服务
4. 密钥应安全存储,不要提交到版本控制
"""
import os
# 生成密钥(实际应用中应存储在安全位置,如环境变量或密钥管理服务)
key = Fernet.generate_key()
cipher_suite = Fernet(key)
# 警告:以下硬编码的凭据仅用于演示
# 生产环境应从环境变量或安全存储中获取
# 例如:username = os.environ.get('APP_USERNAME')
# password = os.environ.get('APP_PASSWORD')
print("警告:以下使用的是演示凭据,请勿在生产环境中使用!")
username = "admin" # 演示用途,实际应从环境变量获取
password = "secure_password" # 演示用途,实际应从环境变量获取
print(f"原始用户名: {username}")
print(f"原始密码: {'*' * len(password)} (已隐藏)")
encrypted_username = cipher_suite.encrypt(username.encode())
encrypted_password = cipher_suite.encrypt(password.encode())
print(f"\n加密后的用户名: {encrypted_username}")
print(f"加密后的密码: {encrypted_password}")
# 解密使用
decrypted_username = cipher_suite.decrypt(encrypted_username).decode()
decrypted_password = cipher_suite.decrypt(encrypted_password).decode()
print(f"\n解密后的用户名: {decrypted_username}")
print(f"解密后的密码: {'*' * len(decrypted_password)} (已隐藏)")
print("\n安全建议:")
print("1. 使用环境变量存储敏感信息: os.environ.get('KEY')")
print("2. 使用 .env 文件配合 python-dotenv 库")
print("3. 考虑使用 AWS KMS、Azure Key Vault 等密钥管理服务")
print("4. 定期轮换密钥和密码")
print("5. 不要将密钥提交到Git等版本控制系统")
def safe_automation_boundaries():
"""
安全自动化边界
"""
# 设置操作边界
SCREEN_WIDTH, SCREEN_HEIGHT = pyautogui.size()
SAFE_AREA = (100, 100, SCREEN_WIDTH - 100, SCREEN_HEIGHT - 100)
def validate_position(x, y):
"""验证位置是否在安全区域内"""
return (SAFE_AREA[0] <= x <= SAFE_AREA[2] and
SAFE_AREA[1] <= y <= SAFE_AREA[3])
def safe_move_to(x, y, duration=0.5):
"""安全移动鼠标"""
if validate_position(x, y):
pyautogui.moveTo(x, y, duration=duration)
print(f"安全移动到 ({x}, {y})")
else:
print(f"位置 ({x}, {y}) 超出安全区域")
# 测试安全移动
safe_move_to(50, 50) # 超出安全区域
safe_move_to(200, 200) # 在安全区域内
safe_move_to(SCREEN_WIDTH - 50, SCREEN_HEIGHT - 50) # 超出安全区域
if __name__ == "__main__":
secure_credentials()
print("\n" + "="*50 + "\n")
safe_automation_boundaries()
8.6.2 权限管理
import pyautogui
import os
import stat
import getpass
def check_permissions():
"""
检查权限
"""
current_user = getpass.getuser()
print(f"当前用户: {current_user}")
# 检查文件权限
test_file = "test.txt"
if not os.path.exists(test_file):
with open(test_file, 'w') as f:
f.write("test")
file_stats = os.stat(test_file)
print(f"文件权限: {oct(file_stats.st_mode)[-3:]}")
# 检查是否有写入权限
if os.access(test_file, os.W_OK):
print("有写入权限")
else:
print("无写入权限")
# 清理测试文件
if os.path.exists(test_file):
os.remove(test_file)
def run_as_admin():
"""
以管理员权限运行
"""
import ctypes
import sys
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
print("当前以管理员权限运行")
# 执行需要管理员权限的操作
pyautogui.moveTo(100, 100)
pyautogui.click()
else:
print("当前未以管理员权限运行")
print("请以管理员权限运行此脚本")
if __name__ == "__main__":
check_permissions()
print("\n" + "="*50 + "\n")
run_as_admin()
8.7 监控与维护
8.7.1 健康检查
import pyautogui
import time
import psutil
import platform
def system_health_check():
"""
系统健康检查
"""
print("系统健康检查:")
# 1. 系统信息
print("\n系统信息:")
print(f"操作系统: {platform.system()} {platform.version()}")
print(f"Python版本: {platform.python_version()}")
# 2. 资源使用
print("\n资源使用:")
cpu_percent = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
disk = psutil.disk_usage('/')
print(f"CPU使用率: {cpu_percent}%")
print(f"内存使用率: {memory.percent}%")
print(f"磁盘使用率: {disk.percent}%")
# 3. 屏幕状态
print("\n屏幕状态:")
screen_width, screen_height = pyautogui.size()
print(f"屏幕分辨率: {screen_width} x {screen_height}")
# 4. 鼠标状态
mouse_x, mouse_y = pyautogui.position()
print(f"鼠标位置: ({mouse_x}, {mouse_y})")
# 5. 网络状态
print("\n网络状态:")
net_io = psutil.net_io_counters()
print(f"发送字节: {net_io.bytes_sent / 1024 / 1024:.2f} MB")
print(f"接收字节: {net_io.bytes_recv / 1024 / 1024:.2f} MB")
def automated_maintenance():
"""
自动化维护
"""
print("自动化维护任务:")
# 1. 清理临时文件
print("\n1. 清理临时文件:")
import tempfile
temp_dir = tempfile.gettempdir()
print(f"临时目录: {temp_dir}")
# 2. 检查更新
print("\n2. 检查更新:")
try:
import pip
result = pip.main(['list', '--outdated'])
if result == 0:
print("更新检查完成")
except Exception as e:
print(f"更新检查失败: {e}")
# 3. 系统重启提示
print("\n3. 系统状态:")
boot_time = psutil.boot_time()
uptime = time.time() - boot_time
uptime_days = uptime / 86400
print(f"系统运行时间: {uptime_days:.1f} 天")
if uptime_days > 7:
print("建议重启系统以保持最佳性能")
if __name__ == "__main__":
system_health_check()
print("\n" + "="*50 + "\n")
automated_maintenance()
8.8 最佳实践总结
8.8.1 生产环境自动化 checklist
# 生产环境自动化 checklist
PRODUCTION_CHECKLIST = [
# 基础配置
"启用 FAILSAFE 机制",
"设置合理的 PAUSE 值",
"配置日志记录",
# 异常处理
"实现全面的异常捕获",
"添加重试机制",
"设置超时处理",
# 性能优化
"使用相对坐标",
"优化截图操作",
"减少不必要的延迟",
# 跨平台兼容
"检测并适配不同平台",
"处理键盘布局差异",
"使用相对路径",
# 安全考虑
"加密敏感信息",
"设置操作边界",
"权限管理",
# 监控与维护
"实现健康检查",
"设置告警机制",
"定期维护",
# CI/CD 集成
"编写自动化测试",
"配置持续集成",
"自动化部署",
]
def run_checklist():
"""
运行生产环境检查清单
"""
print("生产环境自动化检查清单:")
print("=" * 60)
for i, item in enumerate(PRODUCTION_CHECKLIST, 1):
print(f"{i:2d}. {item}")
print("=" * 60)
print("请确保所有项目都已实现")
if __name__ == "__main__":
run_checklist()
8.8.2 自动化脚本模板
"""
PyAutoGUI 生产环境自动化脚本模板
"""
import pyautogui
import time
import logging
import traceback
import argparse
import sys
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('automation.log'),
logging.StreamHandler()
]
)
class AutomationWorkflow:
"""
自动化工作流类
"""
def __init__(self):
self.setup_environment()
def setup_environment(self):
"""
设置环境
"""
# 启用安全机制
pyautogui.FAILSAFE = True
# 设置合理的延迟
pyautogui.PAUSE = 0.1
logging.info("环境设置完成")
def run(self):
"""
运行工作流
"""
try:
logging.info("开始自动化工作流")
# 步骤 1: 准备
self.prepare()
# 步骤 2: 执行主要操作
self.execute_main_operations()
# 步骤 3: 验证结果
self.verify_results()
# 步骤 4: 清理
self.cleanup()
logging.info("工作流执行成功")
return True
except pyautogui.FailSafeException:
logging.warning("检测到 FAILSAFE 信号,工作流已停止")
return False
except Exception as e:
logging.error(f"工作流执行失败: {str(e)}")
logging.error(traceback.format_exc())
return False
def prepare(self):
"""
准备工作
"""
logging.info("执行准备工作")
# 示例:打开应用
# pyautogui.press('win')
# pyautogui.write('notepad')
# pyautogui.press('enter')
# time.sleep(1)
def execute_main_operations(self):
"""
执行主要操作
"""
logging.info("执行主要操作")
# 实现具体的自动化操作
def verify_results(self):
"""
验证结果
"""
logging.info("验证操作结果")
# 实现结果验证
def cleanup(self):
"""
清理工作
"""
logging.info("执行清理工作")
# 实现清理操作
def main():
"""
主函数
"""
parser = argparse.ArgumentParser(description='PyAutoGUI 自动化脚本')
parser.add_argument('--test', action='store_true', help='运行测试模式')
args = parser.parse_args()
workflow = AutomationWorkflow()
success = workflow.run()
if args.test:
logging.info(f"测试模式 - 执行结果: {'成功' if success else '失败'}")
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()
第9章 常见问题与解决方案
9.1 安装与环境问题
9.1.1 安装失败
问题现象:使用 pip install pyautogui 安装失败。
可能原因:
- 网络连接问题
- 依赖库安装失败
- Python版本不兼容
解决方案:
# 1. 确保网络连接正常
# 2. 安装依赖库
pip install Pillow pymsgbox pytweening pyscreeze
# 3. 安装PyAutoGUI
pip install pyautogui
# 4. 完整安装(包含所有依赖)
pip install pyautogui[opencv]
# 5. 对于macOS
pip install pyobjc-core pyobjc
代码示例:
# 检查PyAutoGUI是否安装成功
import pyautogui
print(f"PyAutoGUI版本: {pyautogui.__version__}")
print("安装成功!")
9.1.2 环境依赖问题
问题现象:运行脚本时出现依赖库错误。
可能原因:
- 缺少必要的依赖库
- 依赖库版本不兼容
解决方案:
# 安装所有必要的依赖
pip install -r requirements.txt
requirements.txt:
pillow>=9.0.0
pymsgbox>=1.0.9
pytweening>=1.0.4
pyscreeze>=0.1.28
opencv-python>=4.5.0
9.2 鼠标操作问题
9.2.1 鼠标移动不准确
问题现象:鼠标移动到指定位置时偏差较大。
可能原因:
- 屏幕分辨率设置问题
- DPI缩放影响
- 坐标系统理解错误
解决方案:
import pyautogui
# 1. 获取屏幕尺寸
screen_width, screen_height = pyautogui.size()
print(f"屏幕尺寸: {screen_width} x {screen_height}")
# 2. 检查当前鼠标位置
current_x, current_y = pyautogui.position()
print(f"当前鼠标位置: ({current_x}, {current_y})")
# 3. 使用相对坐标
relative_x = 0.5 # 屏幕宽度的50%
relative_y = 0.5 # 屏幕高度的50%
absolute_x = int(screen_width * relative_x)
absolute_y = int(screen_height * relative_y)
print(f"相对坐标 ({relative_x}, {relative_y}) 转换为绝对坐标 ({absolute_x}, {absolute_y})")
# 4. 移动鼠标
pyautogui.moveTo(absolute_x, absolute_y, duration=0.5)
9.2.2 鼠标点击无效
问题现象:调用 click() 方法但没有实际点击效果。
可能原因:
- 坐标位置错误
- 窗口焦点问题
- 点击时机问题
解决方案:
import pyautogui
import time
def reliable_click(x, y, clicks=1, interval=0.1):
"""
可靠的点击方法
"""
try:
# 移动到目标位置
pyautogui.moveTo(x, y, duration=0.3)
time.sleep(0.2) # 等待稳定
# 执行点击
for i in range(clicks):
pyautogui.mouseDown()
time.sleep(0.05)
pyautogui.mouseUp()
if i < clicks - 1:
time.sleep(interval)
return True
except Exception as e:
print(f"点击失败: {e}")
return False
# 测试可靠点击
if __name__ == "__main__":
# 点击屏幕中心
screen_width, screen_height = pyautogui.size()
center_x, center_y = screen_width // 2, screen_height // 2
print(f"点击屏幕中心: ({center_x}, {center_y})")
reliable_click(center_x, center_y)
9.3 键盘操作问题
9.3.1 键盘输入不生效
问题现象:使用 write() 或 typewrite() 方法时,文本没有输入到目标输入框。
可能原因:
- 目标窗口没有焦点
- 输入时机问题
- 特殊字符处理问题
解决方案:
import pyautogui
import time
def focus_and_type(window_title, text, interval=0.05):
"""
聚焦窗口并输入文本
"""
try:
# 1. 激活窗口(如果使用pygetwindow)
# import pygetwindow
# window = pygetwindow.getWindowsWithTitle(window_title)[0]
# window.activate()
# 2. 或者点击目标区域
# 假设目标输入框在 (300, 300)
pyautogui.click(300, 300)
time.sleep(0.3) # 等待窗口激活
# 3. 输入文本
pyautogui.write(text, interval=interval)
return True
except Exception as e:
print(f"输入失败: {e}")
return False
# 测试
if __name__ == "__main__":
focus_and_type("Notepad", "Hello, PyAutoGUI!")
9.3.2 组合键不生效
问题现象:使用 hotkey() 方法时,组合键没有正确执行。
可能原因:
- 按键顺序问题
- 平台差异
- 按键释放不完整
解决方案:
import pyautogui
import time
def reliable_hotkey(*keys):
"""
可靠的组合键执行方法
"""
try:
# 按下所有键
for key in keys:
pyautogui.keyDown(key)
time.sleep(0.05)
# 释放所有键(反向顺序)
for key in reversed(keys):
pyautogui.keyUp(key)
time.sleep(0.05)
return True
except Exception as e:
print(f"组合键执行失败: {e}")
# 确保所有键都被释放
for key in keys:
try:
pyautogui.keyUp(key)
except:
pass
return False
# 测试
if __name__ == "__main__":
# 测试复制操作
print("执行 Ctrl+C")
reliable_hotkey('ctrl', 'c')
# 测试粘贴操作
time.sleep(1)
print("执行 Ctrl+V")
reliable_hotkey('ctrl', 'v')
9.4 图像识别问题
9.4.1 图像未找到
问题现象:使用 locateOnScreen() 方法时返回 None。
可能原因:
- 图像文件不存在
- 图像与屏幕内容不匹配
- 置信度设置过高
- 屏幕分辨率差异
解决方案:
import pyautogui
import os
def locate_image_with_retry(image_path, max_attempts=3, confidence=0.8, grayscale=False):
"""
带重试机制的图像定位
"""
if not os.path.exists(image_path):
print(f"图像文件不存在: {image_path}")
return None
attempts = 0
while attempts < max_attempts:
try:
position = pyautogui.locateOnScreen(
image_path,
confidence=confidence,
grayscale=grayscale
)
if position:
print(f"找到图像: {image_path}")
return position
else:
attempts += 1
print(f"未找到图像 (尝试 {attempts}/{max_attempts})")
# 降低置信度
confidence -= 0.05
if confidence < 0.6:
break
except Exception as e:
print(f"定位失败: {e}")
attempts += 1
return None
# 测试
if __name__ == "__main__":
image_path = "button.png"
position = locate_image_with_retry(image_path)
if position:
print(f"图像位置: {position}")
# 点击图像中心
center_x = position.left + position.width // 2
center_y = position.top + position.height // 2
pyautogui.click(center_x, center_y)
9.4.2 图像识别速度慢
问题现象:图像识别操作耗时过长。
可能原因:
- 图像尺寸过大
- 搜索区域过大
- 置信度计算复杂
- CPU性能限制
解决方案:
import pyautogui
import time
def optimized_image_recognition(image_path, region=None, confidence=0.8):
"""
优化的图像识别
"""
start_time = time.time()
try:
# 1. 使用区域限制
if region:
position = pyautogui.locateOnScreen(
image_path,
region=region,
confidence=confidence,
grayscale=True # 启用灰度模式加速
)
else:
position = pyautogui.locateOnScreen(
image_path,
confidence=confidence,
grayscale=True
)
elapsed = time.time() - start_time
print(f"识别耗时: {elapsed:.3f}秒")
return position
except Exception as e:
print(f"识别失败: {e}")
return None
# 测试
if __name__ == "__main__":
# 定义搜索区域(屏幕的一部分)
screen_width, screen_height = pyautogui.size()
search_region = (0, 0, screen_width // 2, screen_height)
print("使用区域限制进行图像识别")
position = optimized_image_recognition("button.png", region=search_region)
if position:
print(f"找到图像: {position}")
9.5 屏幕截图问题
9.5.1 截图失败
问题现象:使用 screenshot() 方法时失败或返回空图像。
可能原因:
- 权限不足
- 屏幕分辨率过高
- 内存不足
- 系统限制
解决方案:
import pyautogui
import os
def safe_screenshot(region=None, filename=None):
"""
安全的截图方法
"""
try:
# 1. 检查存储空间
if filename:
dir_path = os.path.dirname(filename)
if dir_path and not os.path.exists(dir_path):
os.makedirs(dir_path)
# 2. 执行截图
if region:
screenshot = pyautogui.screenshot(region=region)
else:
screenshot = pyautogui.screenshot()
# 3. 保存文件
if filename:
screenshot.save(filename)
print(f"截图已保存到: {filename}")
return screenshot
except Exception as e:
print(f"截图失败: {e}")
return None
# 测试
if __name__ == "__main__":
# 测试区域截图
region = (0, 0, 800, 600)
screenshot = safe_screenshot(region=region, filename="region_screenshot.png")
if screenshot:
print(f"截图尺寸: {screenshot.size}")
9.5.2 截图内存占用高
问题现象:截图操作导致内存使用激增。
可能原因:
- 截图尺寸过大
- 频繁截图
- 未及时释放内存
解决方案:
import pyautogui
import gc
import os
def memory_efficient_screenshot(region=None, filename=None):
"""
内存高效的截图方法
"""
try:
# 直接保存到文件,避免在内存中存储
if filename:
if region:
pyautogui.screenshot(filename, region=region)
else:
pyautogui.screenshot(filename)
print(f"截图已保存到: {filename}")
return True
else:
# 只在需要时创建内存中的截图
screenshot = pyautogui.screenshot(region=region)
return screenshot
except Exception as e:
print(f"截图失败: {e}")
return False
finally:
# 强制垃圾回收
gc.collect()
# 测试
if __name__ == "__main__":
print("执行内存高效截图")
# 批量截图示例
for i in range(5):
filename = f"screenshot_{i+1}.png"
memory_efficient_screenshot(filename=filename)
# 处理截图...
# 处理完成后可以删除文件
# os.remove(filename)
9.6 平台兼容性问题
9.6.1 Windows平台问题
问题现象:在Windows系统上运行时出现特殊问题。
可能原因:
- UAC权限问题
- 窗口管理差异
- 键盘布局差异
解决方案:
import pyautogui
import platform
import ctypes
def is_windows():
"""检查是否为Windows平台"""
return platform.system() == "Windows"
def run_as_admin():
"""
检查是否以管理员权限运行
"""
if not is_windows():
return True
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
def windows_specific_fixes():
"""
Windows平台特定修复
"""
if is_windows():
# 禁用Windows键(可选)
# 注意:这需要系统权限
print("应用Windows特定修复")
# 可以在这里添加Windows特定的修复代码
# 测试
if __name__ == "__main__":
print(f"是否为Windows平台: {is_windows()}")
print(f"是否以管理员权限运行: {run_as_admin()}")
windows_specific_fixes()
9.6.2 macOS平台问题
问题现象:在macOS系统上运行时出现特殊问题。
可能原因:
- 权限设置问题
- 辅助功能权限
- 键盘快捷键差异
解决方案:
import pyautogui
import platform
import subprocess
def is_macos():
"""检查是否为macOS平台"""
return platform.system() == "Darwin"
def check_accessibility_permissions():
"""
检查辅助功能权限
"""
if not is_macos():
return True
try:
# 检查辅助功能权限
result = subprocess.run(
["osascript", "-e", "tell application \"System Events\" to get UI elements enabled"],
capture_output=True,
text=True
)
return "true" in result.stdout.lower()
except Exception as e:
print(f"检查权限失败: {e}")
return False
def macos_specific_fixes():
"""
macOS平台特定修复
"""
if is_macos():
print("应用macOS特定修复")
# 可以在这里添加macOS特定的修复代码
# 测试
if __name__ == "__main__":
print(f"是否为macOS平台: {is_macos()}")
if is_macos():
print(f"辅助功能权限: {check_accessibility_permissions()}")
if not check_accessibility_permissions():
print("请在系统偏好设置中启用辅助功能权限")
macos_specific_fixes()
9.7 性能问题
9.7.1 执行速度慢
问题现象:自动化脚本执行速度过慢。
可能原因:
- 默认延迟设置过高
- 不必要的等待时间
- 低效的操作顺序
- 资源密集型操作
解决方案:
import pyautogui
import time
def optimize_performance():
"""
性能优化设置
"""
# 1. 减少默认延迟
original_pause = pyautogui.PAUSE
pyautogui.PAUSE = 0.01 # 减少到10毫秒
try:
# 2. 批量操作
start_time = time.time()
# 优化前
print("优化前:")
for i in range(10):
pyautogui.moveTo(100 + i*20, 100)
pyautogui.click()
time1 = time.time() - start_time
print(f"耗时: {time1:.3f}秒")
# 优化后
start_time = time.time()
print("\n优化后:")
for i in range(10):
x, y = 100 + i*20, 100
pyautogui.moveTo(x, y, duration=0.05)
pyautogui.click()
time2 = time.time() - start_time
print(f"耗时: {time2:.3f}秒")
print(f"性能提升: {((time1 - time2) / time1 * 100):.1f}%")
finally:
# 恢复默认设置
pyautogui.PAUSE = original_pause
# 测试
if __name__ == "__main__":
optimize_performance()
9.7.2 内存使用高
问题现象:脚本运行时内存使用持续增长。
可能原因:
- 未释放的对象
- 频繁的截图操作
- 内存泄漏
解决方案:
import pyautogui
import gc
import psutil
import os
def monitor_memory():
"""
监控内存使用
"""
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024 # MB
def memory_optimization():
"""
内存优化
"""
print(f"初始内存使用: {monitor_memory():.2f} MB")
# 执行内存密集操作
screenshots = []
for i in range(5):
screenshot = pyautogui.screenshot(region=(0, 0, 800, 600))
screenshots.append(screenshot)
print(f"截图 {i+1} 后内存使用: {monitor_memory():.2f} MB")
# 释放内存
print("\n释放内存:")
del screenshots
gc.collect() # 强制垃圾回收
print(f"释放后内存使用: {monitor_memory():.2f} MB")
# 测试
if __name__ == "__main__":
memory_optimization()
9.8 安全问题
9.8.1 FAILSAFE机制问题
问题现象:FAILSAFE机制意外触发。
可能原因:
- 鼠标意外移动到屏幕角落
- 多显示器配置问题
- 脚本逻辑问题
解决方案:
import pyautogui
def configure_failsafe():
"""
配置FAILSAFE机制
注意:FAILSAFE_POINTS 和 FAILSAFE_DISTANCE 不是PyAutoGUI标准属性
PyAutoGUI只支持 FAILSAFE 布尔值设置
"""
# 1. 启用FAILSAFE(推荐)
pyautogui.FAILSAFE = True
print("已启用FAILSAFE机制")
# 2. 自定义安全区域检查(替代方案)
def check_failsafe_area(x_threshold=50, y_threshold=50):
"""
检查鼠标是否在安全区域
Args:
x_threshold: X轴安全阈值(像素)
y_threshold: Y轴安全阈值(像素)
Returns:
bool: 是否在安全区域内
"""
current_pos = pyautogui.position()
return current_pos[0] < x_threshold and current_pos[1] < y_threshold
# 测试自定义安全区域检查
print("\n自定义安全区域检查函数已定义")
print("使用方法: check_failsafe_area(x_threshold, y_threshold)")
print("注意:PyAutoGUI标准库不支持自定义FAILSAFE点或触发距离")
# 测试
if __name__ == "__main__":
configure_failsafe()
print("FAILSAFE配置完成")
9.8.2 权限安全问题
问题现象:脚本需要特殊权限才能运行。
可能原因:
- 需要管理员/root权限
- 需要辅助功能权限
- 文件系统权限问题
解决方案:
import pyautogui
import os
import getpass
def check_permissions():
"""
检查权限
"""
current_user = getpass.getuser()
print(f"当前用户: {current_user}")
# 检查文件权限
test_file = "test_permission.txt"
try:
with open(test_file, 'w') as f:
f.write("test")
print("文件写入权限: 正常")
os.remove(test_file)
except Exception as e:
print(f"文件写入权限: 异常 - {e}")
# 检查屏幕访问权限
try:
size = pyautogui.size()
print(f"屏幕访问权限: 正常 (屏幕尺寸: {size})")
except Exception as e:
print(f"屏幕访问权限: 异常 - {e}")
# 测试
if __name__ == "__main__":
check_permissions()
9.9 其他常见问题
9.9.1 脚本卡死
问题现象:脚本运行过程中突然卡死。
可能原因:
- 无限循环
- 死锁
- 系统资源耗尽
- 异常未捕获
解决方案:
import pyautogui
import time
import signal
import sys
def signal_handler(signal, frame):
"""
信号处理函数
"""
print("\n接收到中断信号,正在退出...")
# 清理操作
sys.exit(0)
def safe_automation():
"""
安全的自动化操作
"""
# 注册信号处理
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
try:
print("开始自动化操作")
print("按 Ctrl+C 停止")
# 模拟长时间操作
for i in range(100):
pyautogui.moveTo(100 + i*10, 100)
time.sleep(0.1)
print(f"执行步骤 {i+1}/100")
print("自动化操作完成")
except Exception as e:
print(f"发生异常: {e}")
# 测试
if __name__ == "__main__":
safe_automation()
9.9.2 坐标计算错误
问题现象:坐标计算错误导致操作位置偏差。
可能原因:
- 屏幕分辨率变化
- 窗口大小变化
- 坐标系统理解错误
- 多显示器配置
解决方案:
import pyautogui
def calculate_relative_coordinates(relative_x, relative_y):
"""
计算相对坐标
Args:
relative_x: 相对X坐标(0.0-1.0)
relative_y: 相对Y坐标(0.0-1.0)
Returns:
tuple: (绝对X坐标, 绝对Y坐标)
"""
screen_width, screen_height = pyautogui.size()
absolute_x = int(screen_width * relative_x)
absolute_y = int(screen_height * relative_y)
return absolute_x, absolute_y
def handle_multi_monitor():
"""
处理多显示器情况
注意:需要使用 screeninfo 库获取多显示器信息
"""
try:
from screeninfo import get_monitors
monitors = get_monitors()
print(f"检测到 {len(monitors)} 个显示器")
for i, monitor in enumerate(monitors):
print(f"显示器 {i+1}:")
print(f" 位置: ({monitor.x}, {monitor.y})")
print(f" 尺寸: {monitor.width} x {monitor.height}")
print(f" 主显示器: {monitor.is_primary}")
except ImportError:
print("未安装 screeninfo 库")
print("运行: pip install screeninfo")
print("\n或者使用以下命令安装:")
print(" Windows: pip install screeninfo")
print(" macOS: pip install screeninfo")
print(" Linux: pip install screeninfo")
except Exception as e:
print(f"获取显示器信息失败: {e}")
# 测试
if __name__ == "__main__":
# 测试相对坐标
rel_x, rel_y = 0.5, 0.5 # 屏幕中心
abs_x, abs_y = calculate_relative_coordinates(rel_x, rel_y)
print(f"相对坐标 ({rel_x}, {rel_y}) 转换为绝对坐标 ({abs_x}, {abs_y})")
# 测试多显示器
handle_multi_monitor()
9.10 问题排查工具
9.10.1 调试工具
import pyautogui
import time
def debug_tool():
"""
调试工具
"""
print("PyAutoGUI调试工具")
print("按 Ctrl+C 退出")
try:
while True:
# 获取鼠标位置
x, y = pyautogui.position()
# 获取像素颜色
color = pyautogui.pixel(x, y)
# 清除屏幕并显示信息
print(f"\r鼠标位置: ({x}, {y}) 颜色: {color}", end='')
time.sleep(0.1)
except KeyboardInterrupt:
print("\n调试工具退出")
def screen_info():
"""
屏幕信息工具
"""
print("屏幕信息:")
width, height = pyautogui.size()
print(f"屏幕尺寸: {width} x {height}")
# 显示常用位置
positions = {
'左上角': (0, 0),
'右上角': (width-1, 0),
'左下角': (0, height-1),
'右下角': (width-1, height-1),
'中心': (width//2, height//2)
}
for name, pos in positions.items():
print(f"{name}: {pos}")
# 测试
if __name__ == "__main__":
screen_info()
print("\n启动鼠标位置调试工具...")
debug_tool()
9.10.2 日志分析工具
import logging
import json
from datetime import datetime
class EnhancedLogger:
"""
增强的日志记录器
"""
def __init__(self, log_file="automation_debug.log"):
self.logger = logging.getLogger("PyAutoGUI-Debug")
self.logger.setLevel(logging.DEBUG)
# 文件处理器
file_handler = logging.FileHandler(log_file)
file_handler.setLevel(logging.DEBUG)
# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 格式化器
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
# 添加处理器
self.logger.addHandler(file_handler)
self.logger.addHandler(console_handler)
def log(self, level, message, **extra):
"""
记录日志
"""
extra_info = " " + " ".join([f"{k}={v}" for k, v in extra.items()]) if extra else ""
if level == "debug":
self.logger.debug(message + extra_info)
elif level == "info":
self.logger.info(message + extra_info)
elif level == "warning":
self.logger.warning(message + extra_info)
elif level == "error":
self.logger.error(message + extra_info)
elif level == "critical":
self.logger.critical(message + extra_info)
# 测试
if __name__ == "__main__":
logger = EnhancedLogger()
logger.log("info", "开始自动化操作")
try:
import pyautogui
logger.log("debug", "PyAutoGUI导入成功", version=pyautogui.__version__)
# 执行一些操作
screen_width, screen_height = pyautogui.size()
logger.log("info", "获取屏幕尺寸", width=screen_width, height=screen_height)
# 模拟错误
# pyautogui.locateOnScreen("non_existent.png")
except Exception as e:
logger.log("error", "操作失败", error=str(e))
logger.log("info", "自动化操作完成")
第10章 实战案例分析
10.1 网页自动化测试案例
10.1.1 登录表单自动填写
功能说明:自动打开浏览器,访问登录页面,填写用户名和密码并提交。
技术要点:
- 浏览器启动与导航
- 元素定位与点击
- 表单填写
- 提交操作
代码实现:
import pyautogui
import time
import os
def web_login_automation():
"""
网页登录自动化
"""
try:
# 1. 启动浏览器
print("启动浏览器...")
if os.name == 'nt': # Windows
os.system('start chrome')
elif os.name == 'posix': # macOS/Linux
if sys.platform == 'darwin': # macOS
os.system('open -a "Google Chrome"')
else: # Linux
os.system('google-chrome &')
time.sleep(3) # 等待浏览器启动
# 2. 访问登录页面
print("访问登录页面...")
pyautogui.write('https://example.com/login', interval=0.05)
pyautogui.press('enter')
time.sleep(3) # 等待页面加载
# 3. 填写用户名
print("填写用户名...")
# 假设用户名输入框在 (500, 300)
pyautogui.click(500, 300)
time.sleep(0.5)
pyautogui.write('testuser', interval=0.05)
# 4. 填写密码
print("填写密码...")
# 假设密码输入框在 (500, 350)
pyautogui.click(500, 350)
time.sleep(0.5)
pyautogui.write('password123', interval=0.05)
# 5. 点击登录按钮
print("点击登录按钮...")
# 假设登录按钮在 (500, 400)
pyautogui.click(500, 400)
time.sleep(2) # 等待登录完成
print("登录自动化完成!")
return True
except Exception as e:
print(f"登录自动化失败: {e}")
return False
# 测试
if __name__ == "__main__":
web_login_automation()
10.1.2 网页数据抓取
功能说明:自动打开网页,抓取指定数据并保存到文件。
技术要点:
- 网页导航
- 数据定位与提取
- 截图与OCR(可选)
- 数据保存
代码实现:
import pyautogui
import time
import os
from PIL import Image
import pytesseract
def web_data_extraction():
"""
网页数据抓取
"""
try:
# 1. 启动浏览器
print("启动浏览器...")
if os.name == 'nt':
os.system('start chrome')
elif os.name == 'posix':
if sys.platform == 'darwin':
os.system('open -a "Google Chrome"')
else:
os.system('google-chrome &')
time.sleep(3)
# 2. 访问目标网页
print("访问目标网页...")
pyautogui.write('https://example.com/data', interval=0.05)
pyautogui.press('enter')
time.sleep(3)
# 3. 定位数据区域并截图
print("抓取数据区域...")
# 假设数据区域在 (200, 200, 800, 600)
region = (200, 200, 600, 400) # (left, top, width, height)
screenshot = pyautogui.screenshot(region=region)
screenshot.save('data_screenshot.png')
print("数据区域已截图保存")
# 4. 使用OCR提取文本(可选)
try:
print("提取文本数据...")
text = pytesseract.image_to_string(screenshot, lang='chi_sim+eng')
print("提取的文本:")
print(text)
# 保存提取的文本
with open('extracted_data.txt', 'w', encoding='utf-8') as f:
f.write(text)
print("文本数据已保存到 extracted_data.txt")
except Exception as e:
print(f"OCR提取失败: {e}")
print("数据抓取完成!")
return True
except Exception as e:
print(f"数据抓取失败: {e}")
return False
# 测试
if __name__ == "__main__":
web_data_extraction()
10.2 桌面应用自动化案例
10.2.1 记事本自动化
功能说明:自动打开记事本,输入文本,保存文件。
技术要点:
- 应用启动
- 文本输入
- 菜单操作
- 文件保存
代码实现:
import pyautogui
import time
import os
def notepad_automation():
"""
记事本自动化
"""
try:
# 1. 启动记事本
print("启动记事本...")
if os.name == 'nt': # Windows
os.system('start notepad')
elif os.name == 'posix': # macOS/Linux
if sys.platform == 'darwin': # macOS
os.system('open -a TextEdit')
else: # Linux
os.system('gedit &')
time.sleep(2) # 等待记事本启动
# 2. 输入文本
print("输入文本...")
text = "Hello, PyAutoGUI!\n"
text += "这是一个自动化测试示例。\n"
text += "通过PyAutoGUI可以实现各种桌面应用的自动化操作。"
pyautogui.write(text, interval=0.05)
time.sleep(1)
# 3. 保存文件
print("保存文件...")
if os.name == 'nt': # Windows
pyautogui.hotkey('ctrl', 's')
elif sys.platform == 'darwin': # macOS
pyautogui.hotkey('command', 's')
else: # Linux
pyautogui.hotkey('ctrl', 's')
time.sleep(1) # 等待保存对话框
# 4. 输入文件名
print("输入文件名...")
filename = "test_automation.txt"
pyautogui.write(filename, interval=0.05)
pyautogui.press('enter')
time.sleep(1)
print("记事本自动化完成!")
print(f"文件已保存为: {filename}")
return True
except Exception as e:
print(f"记事本自动化失败: {e}")
return False
# 测试
if __name__ == "__main__":
notepad_automation()
10.2.2 Excel数据处理
功能说明:自动打开Excel,填充数据,执行计算。
技术要点:
- Excel启动
- 单元格操作
- 公式输入
- 数据填充
代码实现:
import pyautogui
import time
import os
def excel_automation():
"""
Excel自动化
"""
try:
# 1. 启动Excel
print("启动Excel...")
if os.name == 'nt': # Windows
os.system('start excel')
elif sys.platform == 'darwin': # macOS
os.system('open -a Excel')
else: # Linux (使用LibreOffice)
os.system('libreoffice --calc &')
time.sleep(3) # 等待Excel启动
# 2. 输入表头
print("输入表头...")
pyautogui.click(100, 100) # 点击A1单元格
pyautogui.write('产品名称', interval=0.05)
pyautogui.press('tab') # 移动到B1
pyautogui.write('数量', interval=0.05)
pyautogui.press('tab') # 移动到C1
pyautogui.write('单价', interval=0.05)
pyautogui.press('tab') # 移动到D1
pyautogui.write('金额', interval=0.05)
pyautogui.press('enter') # 移动到A2
# 3. 输入数据
print("输入数据...")
products = [
["产品A", "10", "50"],
["产品B", "20", "30"],
["产品C", "15", "40"]
]
for product in products:
pyautogui.write(product[0], interval=0.05)
pyautogui.press('tab')
pyautogui.write(product[1], interval=0.05)
pyautogui.press('tab')
pyautogui.write(product[2], interval=0.05)
pyautogui.press('tab')
# 输入公式:B2*C2
pyautogui.write('=B', interval=0.05)
current_row = pyautogui.position()[1] // 20 + 1 # 估算当前行
pyautogui.write(str(current_row), interval=0.05)
pyautogui.write('*C', interval=0.05)
pyautogui.write(str(current_row), interval=0.05)
pyautogui.press('enter')
# 4. 保存文件
print("保存文件...")
if os.name == 'nt':
pyautogui.hotkey('ctrl', 's')
elif sys.platform == 'darwin':
pyautogui.hotkey('command', 's')
else:
pyautogui.hotkey('ctrl', 's')
time.sleep(1)
pyautogui.write('sales_data.xlsx', interval=0.05)
pyautogui.press('enter')
time.sleep(2)
print("Excel自动化完成!")
print("文件已保存为: sales_data.xlsx")
return True
except Exception as e:
print(f"Excel自动化失败: {e}")
return False
# 测试
if __name__ == "__main__":
excel_automation()
10.3 游戏自动化案例
10.3.1 游戏自动点击
功能说明:自动点击游戏中的特定位置,模拟游戏操作。
技术要点:
- 游戏窗口识别
- 目标位置定位
- 点击操作
- 循环执行
代码实现:
import pyautogui
import time
import random
def game_auto_click():
"""
游戏自动点击
"""
try:
print("游戏自动点击脚本启动")
print("按 Ctrl+C 停止")
# 游戏中需要点击的位置(示例)
click_positions = [
(400, 300), # 位置1
(600, 300), # 位置2
(500, 400), # 位置3
(450, 500), # 位置4
(550, 500) # 位置5
]
# 循环执行
count = 0
start_time = time.time()
while True:
# 随机选择一个位置点击
position = random.choice(click_positions)
# 移动到位置并点击
pyautogui.moveTo(position[0], position[1], duration=0.1)
pyautogui.click()
count += 1
# 随机延迟
delay = random.uniform(0.5, 1.5)
time.sleep(delay)
# 每10次点击显示一次状态
if count % 10 == 0:
elapsed = time.time() - start_time
print(f"已点击 {count} 次,耗时 {elapsed:.1f} 秒")
except KeyboardInterrupt:
print("\n脚本已停止")
except Exception as e:
print(f"脚本执行失败: {e}")
# 测试
if __name__ == "__main__":
game_auto_click()
10.3.2 游戏资源收集
功能说明:自动收集游戏中的资源,包括移动、点击、识别等操作。
技术要点:
- 资源识别
- 路径规划
- 状态判断
- 异常处理
代码实现:
import pyautogui
import time
import os
def game_resource_collection():
"""
游戏资源收集
"""
try:
print("游戏资源收集脚本启动")
print("按 Ctrl+C 停止")
# 资源位置(示例)
resource_positions = [
(300, 200), # 资源1
(500, 250), # 资源2
(700, 200), # 资源3
(400, 400), # 资源4
(600, 400) # 资源5
]
# 基地位置(返回点)
base_position = (900, 500)
# 循环收集资源
collection_count = 0
start_time = time.time()
while True:
# 遍历所有资源位置
for i, pos in enumerate(resource_positions):
print(f"前往收集资源 {i+1}")
# 移动到资源位置
pyautogui.moveTo(pos[0], pos[1], duration=0.5)
time.sleep(0.5)
# 点击收集
pyautogui.click()
print(f"已收集资源 {i+1}")
# 等待收集动画
time.sleep(2)
# 随机延迟,模拟人类操作
time.sleep(random.uniform(0.5, 1.0))
# 返回基地
print("返回基地")
pyautogui.moveTo(base_position[0], base_position[1], duration=0.5)
pyautogui.click()
time.sleep(3) # 等待返回动画
collection_count += 1
elapsed = time.time() - start_time
print(f"\n第 {collection_count} 轮收集完成,耗时 {elapsed:.1f} 秒\n")
# 休息一下
time.sleep(random.uniform(2, 5))
except KeyboardInterrupt:
print("\n脚本已停止")
except Exception as e:
print(f"脚本执行失败: {e}")
# 测试
if __name__ == "__main__":
game_resource_collection()
10.4 数据录入自动化案例
10.4.1 表单自动填写
功能说明:自动填写网页或桌面应用中的表单数据。
技术要点:
- 数据准备
- 表单定位
- 批量填写
- 提交操作
代码实现:
import pyautogui
import time
import csv
def form_auto_fill():
"""
表单自动填写
"""
try:
# 1. 读取数据
print("读取表单数据...")
form_data = []
# 示例数据
form_data = [
{"name": "张三", "email": "zhangsan@example.com", "phone": "13800138001"},
{"name": "李四", "email": "lisi@example.com", "phone": "13900139001"},
{"name": "王五", "email": "wangwu@example.com", "phone": "13700137001"}
]
print(f"读取到 {len(form_data)} 条数据")
# 2. 打开表单页面
print("打开表单页面...")
# 这里可以根据实际情况打开相应的应用或网页
# 示例:打开浏览器
import os
if os.name == 'nt':
os.system('start chrome')
elif os.name == 'posix':
if sys.platform == 'darwin':
os.system('open -a "Google Chrome"')
else:
os.system('google-chrome &')
time.sleep(3)
pyautogui.write('https://example.com/form', interval=0.05)
pyautogui.press('enter')
time.sleep(3)
# 3. 循环填写表单
for i, data in enumerate(form_data):
print(f"填写第 {i+1} 条数据...")
# 填写姓名
print(" 填写姓名...")
pyautogui.click(400, 200) # 假设姓名输入框位置
time.sleep(0.5)
pyautogui.write(data["name"], interval=0.05)
# 填写邮箱
print(" 填写邮箱...")
pyautogui.click(400, 250) # 假设邮箱输入框位置
time.sleep(0.5)
pyautogui.write(data["email"], interval=0.05)
# 填写电话
print(" 填写电话...")
pyautogui.click(400, 300) # 假设电话输入框位置
time.sleep(0.5)
pyautogui.write(data["phone"], interval=0.05)
# 提交表单
print(" 提交表单...")
pyautogui.click(400, 350) # 假设提交按钮位置
time.sleep(2) # 等待提交完成
# 刷新页面或打开新表单
print(" 准备下一条...")
pyautogui.hotkey('ctrl', 'r') # 刷新页面
time.sleep(3) # 等待页面加载
print("表单填写完成!")
return True
except Exception as e:
print(f"表单填写失败: {e}")
return False
# 测试
if __name__ == "__main__":
form_auto_fill()
10.4.2 批量数据导入
功能说明:从Excel或CSV文件批量导入数据到目标应用。
技术要点:
- 数据读取
- 应用操作
- 批量处理
- 错误处理
代码实现:
import pyautogui
import time
import csv
import os
def batch_data_import():
"""
批量数据导入
"""
try:
# 1. 准备数据文件
print("准备数据文件...")
# 创建示例数据
with open('import_data.csv', 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['姓名', '年龄', '部门'])
writer.writerow(['张三', '25', '技术部'])
writer.writerow(['李四', '30', '市场部'])
writer.writerow(['王五', '28', '财务部'])
print("数据文件已创建: import_data.csv")
# 2. 打开目标应用
print("打开目标应用...")
# 示例:打开Excel
if os.name == 'nt':
os.system('start excel')
elif sys.platform == 'darwin':
os.system('open -a Excel')
else:
os.system('libreoffice --calc &')
time.sleep(3)
# 3. 导入数据
print("开始导入数据...")
# 模拟导入操作
# 实际应用中需要根据目标应用的导入流程进行调整
# 点击数据菜单
pyautogui.click(100, 50) # 假设数据菜单位置
time.sleep(0.5)
# 选择导入选项
pyautogui.click(150, 150) # 假设导入选项位置
time.sleep(1)
# 选择CSV文件
pyautogui.write('import_data.csv', interval=0.05)
pyautogui.press('enter')
time.sleep(2)
# 完成导入向导
pyautogui.click(500, 400) # 假设下一步按钮位置
time.sleep(1)
pyautogui.click(500, 400) # 假设完成按钮位置
time.sleep(3)
print("数据导入完成!")
return True
except Exception as e:
print(f"数据导入失败: {e}")
return False
# 测试
if __name__ == "__main__":
batch_data_import()
10.5 截图与监控自动化案例
10.5.1 定时截图监控
功能说明:定时截取屏幕内容,用于监控系统状态或应用运行情况。
技术要点:
- 定时操作
- 屏幕截图
- 文件管理
- 异常处理
代码实现:
import pyautogui
import time
import os
from datetime import datetime
def定时_screenshot_monitoring(interval=60, duration=3600):
"""
定时截图监控
Args:
interval: 截图间隔(秒)
duration: 监控持续时间(秒)
"""
try:
# 创建截图保存目录
save_dir = 'screenshots'
if not os.path.exists(save_dir):
os.makedirs(save_dir)
print(f"开始定时截图监控")
print(f"截图间隔: {interval}秒")
print(f"监控持续时间: {duration}秒")
print("按 Ctrl+C 停止")
start_time = time.time()
screenshot_count = 0
while time.time() - start_time < duration:
# 生成文件名
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = os.path.join(save_dir, f'screenshot_{timestamp}.png')
# 执行截图
print(f"截取屏幕...")
screenshot = pyautogui.screenshot()
screenshot.save(filename)
screenshot_count += 1
print(f"截图已保存: {filename}")
print(f"已截取 {screenshot_count} 张图片")
# 等待下一次截图
time.sleep(interval)
print(f"\n监控完成")
print(f"总共截取 {screenshot_count} 张图片")
print(f"图片保存目录: {os.path.abspath(save_dir)}")
return True
except KeyboardInterrupt:
print("\n监控已停止")
return False
except Exception as e:
print(f"监控失败: {e}")
return False
# 测试
if __name__ == "__main__":
定时_screenshot_monitoring(interval=10, duration=60) # 每10秒截图一次,持续1分钟
10.5.2 屏幕变化监控
功能说明:监控屏幕特定区域的变化,当检测到变化时触发操作。
技术要点:
- 区域监控
- 图像比较
- 变化检测
- 触发操作
代码实现:
import pyautogui
import time
import os
from PIL import ImageChops
from PIL import Image
def screen_change_monitoring(region=None, threshold=1000):
"""
屏幕变化监控
Args:
region: 监控区域 (left, top, width, height)
threshold: 变化阈值
"""
try:
print("开始屏幕变化监控")
print("按 Ctrl+C 停止")
# 默认监控整个屏幕
if not region:
screen_width, screen_height = pyautogui.size()
region = (0, 0, screen_width, screen_height)
print(f"监控区域: {region}")
print(f"变化阈值: {threshold}")
# 获取初始屏幕状态
previous_screenshot = pyautogui.screenshot(region=region)
change_count = 0
start_time = time.time()
while True:
# 获取当前屏幕状态
current_screenshot = pyautogui.screenshot(region=region)
# 比较屏幕变化
diff = ImageChops.difference(previous_screenshot, current_screenshot)
diff_value = sum(diff.convert('L').getdata())
# 检测到变化
if diff_value > threshold:
change_count += 1
timestamp = time.strftime('%Y%m%d_%H%M%S')
# 保存变化前后的截图
if not os.path.exists('screen_changes'):
os.makedirs('screen_changes')
previous_screenshot.save(f'screen_changes/previous_{timestamp}.png')
current_screenshot.save(f'screen_changes/current_{timestamp}.png')
print(f"\n检测到屏幕变化 #{change_count}")
print(f"变化值: {diff_value}")
print(f"截图已保存到 screen_changes 目录")
# 更新基准截图
previous_screenshot = current_screenshot
# 可以在这里添加触发操作,如发送通知等
# 短暂延迟
time.sleep(1)
except KeyboardInterrupt:
print("\n监控已停止")
print(f"总共检测到 {change_count} 次变化")
except Exception as e:
print(f"监控失败: {e}")
# 测试
if __name__ == "__main__":
# 监控屏幕中央区域
screen_width, screen_height = pyautogui.size()
monitor_region = (
screen_width // 4,
screen_height // 4,
screen_width // 2,
screen_height // 2
)
screen_change_monitoring(region=monitor_region)
10.6 综合自动化案例
10.6.1 系统维护自动化
功能说明:自动执行系统维护任务,如清理临时文件、检查更新、备份数据等。
技术要点:
- 多任务协调
- 系统操作
- 错误处理
- 日志记录
代码实现:
import pyautogui
import time
import os
import shutil
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='system_maintenance.log'
)
def system_maintenance():
"""
系统维护自动化
"""
try:
logging.info("开始系统维护")
print("开始系统维护...")
# 1. 清理临时文件
print("1. 清理临时文件...")
try:
import tempfile
temp_dir = tempfile.gettempdir()
logging.info(f"清理临时目录: {temp_dir}")
# 清理临时文件(示例)
for file in os.listdir(temp_dir):
file_path = os.path.join(temp_dir, file)
try:
if os.path.isfile(file_path):
os.remove(file_path)
logging.info(f"删除临时文件: {file}")
except Exception as e:
logging.warning(f"无法删除文件 {file}: {e}")
print("临时文件清理完成")
except Exception as e:
logging.error(f"清理临时文件失败: {e}")
print(f"清理临时文件失败: {e}")
# 2. 检查系统更新
print("\n2. 检查系统更新...")
try:
if os.name == 'nt': # Windows
print("检查Windows更新...")
# 这里可以添加Windows更新检查代码
elif os.name == 'posix': # macOS/Linux
if sys.platform == 'darwin': # macOS
print("检查macOS更新...")
# 这里可以添加macOS更新检查代码
else: # Linux
print("检查Linux更新...")
# 这里可以添加Linux更新检查代码
print("系统更新检查完成")
except Exception as e:
logging.error(f"检查系统更新失败: {e}")
print(f"检查系统更新失败: {e}")
# 3. 备份重要数据
print("\n3. 备份重要数据...")
try:
# 创建备份目录
backup_dir = f'backup_{time.strftime("%Y%m%d")}'
if not os.path.exists(backup_dir):
os.makedirs(backup_dir)
# 示例:备份文档目录
documents_dir = os.path.expanduser('~\Documents') if os.name == 'nt' else os.path.expanduser('~/Documents')
if os.path.exists(documents_dir):
backup_documents = os.path.join(backup_dir, 'Documents')
shutil.copytree(documents_dir, backup_documents, ignore=shutil.ignore_patterns('*.tmp', '*.log'))
logging.info(f"备份文档目录到: {backup_documents}")
print("文档目录备份完成")
except Exception as e:
logging.error(f"备份数据失败: {e}")
print(f"备份数据失败: {e}")
# 4. 系统健康检查
print("\n4. 系统健康检查...")
try:
import psutil
# 检查CPU使用率
cpu_percent = psutil.cpu_percent(interval=1)
logging.info(f"CPU使用率: {cpu_percent}%")
print(f"CPU使用率: {cpu_percent}%")
# 检查内存使用率
memory = psutil.virtual_memory()
logging.info(f"内存使用率: {memory.percent}%")
print(f"内存使用率: {memory.percent}%")
# 检查磁盘使用率
disk = psutil.disk_usage('/')
logging.info(f"磁盘使用率: {disk.percent}%")
print(f"磁盘使用率: {disk.percent}%")
except Exception as e:
logging.error(f"系统健康检查失败: {e}")
print(f"系统健康检查失败: {e}")
logging.info("系统维护完成")
print("\n系统维护完成!")
return True
except Exception as e:
logging.error(f"系统维护失败: {e}")
print(f"系统维护失败: {e}")
return False
# 测试
if __name__ == "__main__":
system_maintenance()
10.6.2 多应用协同自动化
功能说明:协调多个应用之间的操作,实现复杂的工作流程自动化。
技术要点:
- 多应用切换
- 数据传递
- 工作流程控制
- 异常处理
代码实现:
import pyautogui
import time
import os
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='multi_app_automation.log'
)
def multi_app_automation():
"""
多应用协同自动化
"""
try:
logging.info("开始多应用协同自动化")
print("开始多应用协同自动化...")
# 1. 打开浏览器并获取数据
print("1. 打开浏览器并获取数据...")
if os.name == 'nt':
os.system('start chrome')
elif os.name == 'posix':
if sys.platform == 'darwin':
os.system('open -a "Google Chrome"')
else:
os.system('google-chrome &')
time.sleep(3)
pyautogui.write('https://example.com/data', interval=0.05)
pyautogui.press('enter')
time.sleep(3)
# 假设在网页上获取数据
print("获取网页数据...")
# 这里可以添加数据获取代码
# 2. 打开Excel并处理数据
print("\n2. 打开Excel并处理数据...")
if os.name == 'nt':
os.system('start excel')
elif sys.platform == 'darwin':
os.system('open -a Excel')
else:
os.system('libreoffice --calc &')
time.sleep(3)
# 处理数据
print("在Excel中处理数据...")
# 这里可以添加Excel操作代码
# 3. 打开Word并生成报告
print("\n3. 打开Word并生成报告...")
if os.name == 'nt':
os.system('start winword')
elif sys.platform == 'darwin':
os.system('open -a Word')
else:
os.system('libreoffice --writer &')
time.sleep(3)
# 生成报告
print("在Word中生成报告...")
# 这里可以添加Word操作代码
# 4. 保存并关闭所有应用
print("\n4. 保存并关闭所有应用...")
# 保存Word文档
if os.name == 'nt':
pyautogui.hotkey('ctrl', 's')
elif sys.platform == 'darwin':
pyautogui.hotkey('command', 's')
else:
pyautogui.hotkey('ctrl', 's')
time.sleep(1)
pyautogui.write('report.docx', interval=0.05)
pyautogui.press('enter')
time.sleep(1)
# 保存Excel文件
# 切换到Excel窗口(这里需要根据实际情况调整)
pyautogui.hotkey('alt', 'tab')
time.sleep(1)
if os.name == 'nt':
pyautogui.hotkey('ctrl', 's')
elif sys.platform == 'darwin':
pyautogui.hotkey('command', 's')
else:
pyautogui.hotkey('ctrl', 's')
time.sleep(1)
pyautogui.write('data.xlsx', interval=0.05)
pyautogui.press('enter')
time.sleep(1)
logging.info("多应用协同自动化完成")
print("\n多应用协同自动化完成!")
return True
except Exception as e:
logging.error(f"多应用协同自动化失败: {e}")
print(f"多应用协同自动化失败: {e}")
return False
# 测试
if __name__ == "__main__":
multi_app_automation()
10.7 案例总结与最佳实践
10.7.1 案例实施步骤
- 需求分析:明确自动化目标和范围
- 环境准备:安装必要的依赖和工具
- 脚本设计:规划自动化流程和步骤
- 代码实现:编写自动化脚本
- 测试验证:在测试环境中验证脚本
- 部署运行:在生产环境中部署和运行
- 监控维护:监控脚本运行状态并定期维护
10.7.2 最佳实践建议
- 模块化设计:将功能拆分为独立的函数,提高代码可维护性
- 异常处理:全面捕获和处理异常,确保脚本稳定运行
- 日志记录:详细记录脚本运行状态和错误信息
- 参数化配置:使用配置文件或命令行参数,提高脚本灵活性
- 性能优化:优化执行速度和内存使用
- 安全性:保护敏感信息,设置安全边界
- 可扩展性:设计可扩展的架构,便于添加新功能
- 文档化:编写详细的文档,说明脚本功能和使用方法
10.7.3 常见陷阱与避免方法
| 陷阱 | 避免方法 |
|---|---|
| 硬编码坐标 | 使用相对坐标或图像识别 |
| 固定延迟 | 使用动态等待或状态检测 |
| 缺少异常处理 | 全面捕获异常并添加重试机制 |
| 内存泄漏 | 及时释放资源,使用上下文管理器 |
| 安全风险 | 加密敏感信息,设置操作边界 |
| 平台兼容性 | 添加平台检测和适配代码 |
| 性能问题 | 优化算法,减少不必要的操作 |
| 维护困难 | 模块化设计,编写详细文档 |
10.8 未来发展趋势
10.8.1 技术发展方向
- AI 集成:结合人工智能技术,实现更智能的自动化
- 云服务:将自动化任务部署到云端,实现远程管理
- 容器化:使用Docker等容器技术,提高环境一致性
- 低代码平台:开发可视化的自动化配置平台
- 多设备协同:实现跨设备的自动化操作
10.8.2 行业应用前景
- 测试自动化:更智能、更全面的测试自动化
- 业务流程自动化:企业级业务流程的自动化
- 智能运维:IT系统的智能监控和维护
- 智能家居:家庭设备的自动化控制
- 工业自动化:工业生产流程的自动化
10.9 实战案例模板
10.9.1 通用自动化脚本模板
"""
PyAutoGUI 实战案例模板
"""
import pyautogui
import time
import logging
import argparse
import sys
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('automation.log'),
logging.StreamHandler()
]
)
class AutomationTask:
"""
自动化任务类
"""
def __init__(self, config=None):
self.config = config or {}
self.setup()
def setup(self):
"""
初始化设置
"""
# 启用安全机制
pyautogui.FAILSAFE = True
# 设置合理的延迟
pyautogui.PAUSE = self.config.get('pause', 0.1)
logging.info("环境设置完成")
def run(self):
"""
运行自动化任务
"""
try:
logging.info("开始自动化任务")
# 步骤1: 准备
self.prepare()
# 步骤2: 执行主要操作
self.execute()
# 步骤3: 验证结果
self.verify()
# 步骤4: 清理
self.cleanup()
logging.info("自动化任务执行成功")
return True
except pyautogui.FailSafeException:
logging.warning("检测到 FAILSAFE 信号,任务已停止")
return False
except Exception as e:
logging.error(f"任务执行失败: {str(e)}")
logging.error(traceback.format_exc())
return False
def prepare(self):
"""
准备工作
"""
logging.info("执行准备工作")
# 实现准备逻辑
def execute(self):
"""
执行主要操作
"""
logging.info("执行主要操作")
# 实现主要操作逻辑
def verify(self):
"""
验证结果
"""
logging.info("验证操作结果")
# 实现验证逻辑
def cleanup(self):
"""
清理工作
"""
logging.info("执行清理工作")
# 实现清理逻辑
def main():
"""
主函数
"""
parser = argparse.ArgumentParser(description='PyAutoGUI 自动化脚本')
parser.add_argument('--config', type=str, help='配置文件路径')
parser.add_argument('--test', action='store_true', help='运行测试模式')
args = parser.parse_args()
# 加载配置
config = {}
if args.config:
try:
import json
with open(args.config, 'r') as f:
config = json.load(f)
except Exception as e:
logging.error(f"加载配置文件失败: {e}")
# 创建并运行任务
task = AutomationTask(config)
success = task.run()
if args.test:
logging.info(f"测试模式 - 执行结果: {'成功' if success else '失败'}")
sys.exit(0 if success else 1)
if __name__ == "__main__":
main()
10.9.2 项目结构模板
automation_project/
├── main.py # 主脚本
├── config.json # 配置文件
├── modules/ # 模块目录
│ ├── __init__.py
│ ├── browser.py # 浏览器自动化
│ ├── desktop.py # 桌面应用自动化
│ └── utils.py # 工具函数
├── resources/ # 资源目录
│ ├── images/ # 图像文件
│ └── data/ # 数据文件
├── logs/ # 日志目录
└── README.md # 项目说明
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)