添加窗口钓鱼自动化脚本
- 实现窗口识别和激活功能 - 添加钓鱼和收杆消息发送 - 支持可配置时间间隔和循环次数 - 包含完整的日志记录和错误处理 - 提供测试模式和详细文档 - 添加.gitignore和requirements.txt
This commit is contained in:
49
.gitignore
vendored
Normal file
49
.gitignore
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# Python
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.so
|
||||
.Python
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdk/
|
||||
var/
|
||||
wheels/
|
||||
share/python-wheels/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
MANIFEST
|
||||
|
||||
# Virtual environments
|
||||
.env
|
||||
.venv
|
||||
env/
|
||||
venv/
|
||||
ENV/
|
||||
env.bak/
|
||||
venv.bak/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
fishing_bot.log
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# System
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Claude Code
|
||||
.claude/
|
||||
136
README.md
Normal file
136
README.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# 窗口钓鱼自动化脚本
|
||||
|
||||
这是一个用于自动化钓鱼操作的Python脚本,可以识别指定窗口并循环发送钓鱼和收杆消息。
|
||||
|
||||
## 功能特点
|
||||
|
||||
- 自动查找并激活目标窗口
|
||||
- 发送钓鱼和收杆消息(可自定义按键)
|
||||
- 时间间隔可配置
|
||||
- 支持有限循环或无限循环
|
||||
- 完整的日志记录
|
||||
- 错误处理和重试机制
|
||||
|
||||
## 系统要求
|
||||
|
||||
- Python 3.6+
|
||||
- Windows系统(支持macOS/Linux但可能需要调整)
|
||||
|
||||
## 安装依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
或者手动安装:
|
||||
|
||||
```bash
|
||||
pip install pyautogui pygetwindow
|
||||
```
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 基本使用
|
||||
|
||||
```bash
|
||||
# 使用默认设置(窗口标题包含"魔兽世界",间隔5秒,无限循环)
|
||||
python main.py
|
||||
|
||||
# 指定窗口标题和间隔
|
||||
python main.py --window "游戏窗口" --interval 10.0
|
||||
|
||||
# 指定循环次数
|
||||
python main.py --window "游戏窗口" --cycles 100
|
||||
|
||||
# 测试模式(检查功能是否正常)
|
||||
python main.py --test
|
||||
```
|
||||
|
||||
### 命令行参数
|
||||
|
||||
| 参数 | 简写 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `--window` | `-w` | `"魔兽世界"` | 目标窗口标题(支持部分匹配) |
|
||||
| `--interval` | `-i` | `5.0` | 钓鱼和收杆之间的时间间隔(秒) |
|
||||
| `--cycles` | `-c` | `0` | 循环次数(0表示无限循环) |
|
||||
| `--test` | `-t` | `False` | 测试模式,只运行一个周期并显示详细信息 |
|
||||
|
||||
### 自定义按键
|
||||
|
||||
如果需要修改发送钓鱼/收杆消息的按键,请编辑 `main.py` 文件中的以下方法:
|
||||
|
||||
1. `send_fishing_message()` - 默认按 'F' 键
|
||||
2. `send_reel_message()` - 默认按空格键
|
||||
|
||||
可以修改为其他按键,例如:
|
||||
|
||||
```python
|
||||
# 改为按 '1' 键
|
||||
pyautogui.press('1')
|
||||
|
||||
# 组合键
|
||||
pyautogui.hotkey('ctrl', 'f')
|
||||
|
||||
# 鼠标点击
|
||||
pyautogui.click(x=100, y=200)
|
||||
```
|
||||
|
||||
## 稳定性验证
|
||||
|
||||
脚本包含以下稳定性措施:
|
||||
|
||||
1. **错误处理**:所有关键操作都有try-catch保护
|
||||
2. **日志记录**:详细日志记录到文件和终端
|
||||
3. **窗口重试**:每次循环都会重新查找窗口,避免窗口丢失
|
||||
4. **用户中断**:支持Ctrl+C安全退出
|
||||
5. **资源管理**:循环间有短暂暂停,避免CPU占用过高
|
||||
|
||||
### 验证方法
|
||||
|
||||
1. **功能测试**:
|
||||
```bash
|
||||
python main.py --test
|
||||
```
|
||||
检查是否能正确找到窗口、激活窗口。
|
||||
|
||||
2. **短期运行测试**:
|
||||
```bash
|
||||
python main.py --cycles 10 --interval 2
|
||||
```
|
||||
运行10个周期,观察是否有错误。
|
||||
|
||||
3. **日志检查**:
|
||||
查看 `fishing_bot.log` 文件,确认没有异常错误。
|
||||
|
||||
4. **压力测试**:
|
||||
```bash
|
||||
# 长时间运行(如1000个周期)
|
||||
python main.py --cycles 1000 --interval 5
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **窗口焦点**:脚本需要激活目标窗口,期间不要操作鼠标键盘
|
||||
2. **时间间隔**:根据实际游戏需要调整间隔时间
|
||||
3. **防检测**:某些游戏禁止自动化,使用前请了解游戏规则
|
||||
4. **分辨率**:脚本不依赖于屏幕坐标,但窗口需要可见
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 找不到窗口
|
||||
- 确认窗口标题正确
|
||||
- 窗口是否最小化或隐藏
|
||||
- 尝试使用部分标题匹配
|
||||
|
||||
### 按键不起作用
|
||||
- 确认游戏窗口处于激活状态
|
||||
- 检查游戏按键设置
|
||||
- 尝试增加激活后的等待时间
|
||||
|
||||
### 权限问题
|
||||
- 以管理员身份运行(某些游戏需要)
|
||||
- 关闭杀毒软件或防火墙的干扰
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License
|
||||
250
main.py
Normal file
250
main.py
Normal file
@@ -0,0 +1,250 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
窗口钓鱼自动化脚本
|
||||
功能:识别指定窗口,循环发送钓鱼和收杆消息,时间间隔相等
|
||||
"""
|
||||
|
||||
import time
|
||||
import logging
|
||||
import sys
|
||||
from typing import Optional
|
||||
|
||||
# 尝试导入自动化库,如果缺失则提示安装
|
||||
try:
|
||||
import pyautogui
|
||||
import pygetwindow as gw
|
||||
except ImportError as e:
|
||||
print(f"缺少依赖库: {e}")
|
||||
print("请使用 pip install pyautogui pygetwindow 安装")
|
||||
sys.exit(1)
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format='%(asctime)s - %(levelname)s - %(message)s',
|
||||
handlers=[
|
||||
logging.FileHandler('fishing_bot.log', encoding='utf-8'),
|
||||
logging.StreamHandler()
|
||||
]
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class FishingBot:
|
||||
def __init__(self, window_title: str, interval: float = 5.0):
|
||||
"""
|
||||
初始化钓鱼机器人
|
||||
|
||||
Args:
|
||||
window_title: 窗口标题(支持部分匹配)
|
||||
interval: 钓鱼和收杆之间的时间间隔(秒)
|
||||
"""
|
||||
self.window_title = window_title
|
||||
self.interval = interval
|
||||
self.running = False
|
||||
|
||||
def find_window(self) -> Optional[gw.Window]:
|
||||
"""
|
||||
查找包含指定标题的窗口
|
||||
|
||||
Returns:
|
||||
找到的窗口对象,如果未找到则返回None
|
||||
"""
|
||||
try:
|
||||
windows = gw.getWindowsWithTitle(self.window_title)
|
||||
if windows:
|
||||
logger.info(f"找到窗口: {windows[0].title}")
|
||||
return windows[0]
|
||||
else:
|
||||
logger.warning(f"未找到包含标题 '{self.window_title}' 的窗口")
|
||||
return None
|
||||
except Exception as e:
|
||||
logger.error(f"查找窗口时出错: {e}")
|
||||
return None
|
||||
|
||||
def activate_window(self, window: gw.Window) -> bool:
|
||||
"""
|
||||
激活指定窗口
|
||||
|
||||
Args:
|
||||
window: 窗口对象
|
||||
|
||||
Returns:
|
||||
是否成功激活
|
||||
"""
|
||||
try:
|
||||
window.activate()
|
||||
time.sleep(0.5) # 等待窗口激活
|
||||
logger.info(f"已激活窗口: {window.title}")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"激活窗口时出错: {e}")
|
||||
return False
|
||||
|
||||
def send_fishing_message(self) -> bool:
|
||||
"""
|
||||
发送钓鱼消息
|
||||
|
||||
Returns:
|
||||
是否成功发送
|
||||
"""
|
||||
try:
|
||||
# 这里根据实际需要修改发送方式
|
||||
# 示例:模拟按下'F'键(常见游戏钓鱼键)
|
||||
pyautogui.press('f')
|
||||
logger.info("发送钓鱼消息")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"发送钓鱼消息时出错: {e}")
|
||||
return False
|
||||
|
||||
def send_reel_message(self) -> bool:
|
||||
"""
|
||||
发送收杆消息
|
||||
|
||||
Returns:
|
||||
是否成功发送
|
||||
"""
|
||||
try:
|
||||
# 这里根据实际需要修改发送方式
|
||||
# 示例:模拟按下空格键(常见游戏收杆键)
|
||||
pyautogui.press('space')
|
||||
logger.info("发送收杆消息")
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.error(f"发送收杆消息时出错: {e}")
|
||||
return False
|
||||
|
||||
def run_cycle(self) -> bool:
|
||||
"""
|
||||
运行一个完整的钓鱼周期
|
||||
|
||||
Returns:
|
||||
周期是否成功完成
|
||||
"""
|
||||
# 查找窗口
|
||||
window = self.find_window()
|
||||
if not window:
|
||||
logger.error("无法找到目标窗口,跳过本次周期")
|
||||
return False
|
||||
|
||||
# 激活窗口
|
||||
if not self.activate_window(window):
|
||||
logger.error("无法激活窗口,跳过本次周期")
|
||||
return False
|
||||
|
||||
# 发送钓鱼消息
|
||||
if not self.send_fishing_message():
|
||||
logger.error("发送钓鱼消息失败,跳过本次周期")
|
||||
return False
|
||||
|
||||
# 等待间隔
|
||||
logger.info(f"等待 {self.interval} 秒...")
|
||||
time.sleep(self.interval)
|
||||
|
||||
# 发送收杆消息
|
||||
if not self.send_reel_message():
|
||||
logger.error("发送收杆消息失败")
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def start(self, cycles: int = 0):
|
||||
"""
|
||||
启动钓鱼机器人
|
||||
|
||||
Args:
|
||||
cycles: 循环次数,0表示无限循环
|
||||
"""
|
||||
self.running = True
|
||||
cycle_count = 0
|
||||
|
||||
logger.info(f"开始钓鱼机器人,窗口标题: '{self.window_title}', 间隔: {self.interval}秒")
|
||||
|
||||
try:
|
||||
while self.running:
|
||||
cycle_count += 1
|
||||
logger.info(f"开始第 {cycle_count} 个周期")
|
||||
|
||||
success = self.run_cycle()
|
||||
|
||||
if success:
|
||||
logger.info(f"第 {cycle_count} 个周期完成")
|
||||
else:
|
||||
logger.warning(f"第 {cycle_count} 个周期失败")
|
||||
|
||||
# 如果指定了循环次数且已达到,则停止
|
||||
if cycles > 0 and cycle_count >= cycles:
|
||||
logger.info(f"已完成指定的 {cycles} 个周期")
|
||||
break
|
||||
|
||||
# 周期之间的短暂暂停,避免CPU占用过高
|
||||
time.sleep(1)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
logger.info("用户中断执行")
|
||||
except Exception as e:
|
||||
logger.error(f"运行时发生未预期错误: {e}")
|
||||
finally:
|
||||
self.running = False
|
||||
logger.info("钓鱼机器人已停止")
|
||||
|
||||
def stop(self):
|
||||
"""停止钓鱼机器人"""
|
||||
self.running = False
|
||||
logger.info("停止信号已发送")
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='窗口钓鱼自动化脚本')
|
||||
parser.add_argument('--window', '-w', default='魔兽世界',
|
||||
help='目标窗口标题(支持部分匹配)')
|
||||
parser.add_argument('--interval', '-i', type=float, default=5.0,
|
||||
help='钓鱼和收杆之间的时间间隔(秒)')
|
||||
parser.add_argument('--cycles', '-c', type=int, default=0,
|
||||
help='循环次数(0表示无限循环)')
|
||||
parser.add_argument('--test', '-t', action='store_true',
|
||||
help='测试模式:只运行一个周期并显示详细信息')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# 创建机器人实例
|
||||
bot = FishingBot(args.window, args.interval)
|
||||
|
||||
if args.test:
|
||||
logger.info("=== 测试模式 ===")
|
||||
logger.info(f"窗口标题: {args.window}")
|
||||
logger.info(f"间隔: {args.interval}秒")
|
||||
|
||||
# 测试窗口查找
|
||||
window = bot.find_window()
|
||||
if window:
|
||||
logger.info(f"✓ 找到窗口: {window.title}")
|
||||
else:
|
||||
logger.error("✗ 未找到窗口")
|
||||
return
|
||||
|
||||
# 测试激活
|
||||
if bot.activate_window(window):
|
||||
logger.info("✓ 窗口激活成功")
|
||||
else:
|
||||
logger.error("✗ 窗口激活失败")
|
||||
return
|
||||
|
||||
logger.info("测试完成,请检查日志确认功能正常")
|
||||
return
|
||||
|
||||
# 启动机器人
|
||||
try:
|
||||
bot.start(args.cycles)
|
||||
except KeyboardInterrupt:
|
||||
logger.info("脚本被用户中断")
|
||||
except Exception as e:
|
||||
logger.error(f"脚本执行出错: {e}")
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
4
requirements.txt
Normal file
4
requirements.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
pyautogui==0.9.54
|
||||
pygetwindow==0.0.9
|
||||
# 如果需要跨平台支持,可以添加以下库
|
||||
# pynput==1.7.6
|
||||
Reference in New Issue
Block a user