添加窗口钓鱼自动化脚本

- 实现窗口识别和激活功能
- 添加钓鱼和收杆消息发送
- 支持可配置时间间隔和循环次数
- 包含完整的日志记录和错误处理
- 提供测试模式和详细文档
- 添加.gitignore和requirements.txt
This commit is contained in:
Ke
2026-04-02 14:54:45 +08:00
commit 8960436379
4 changed files with 439 additions and 0 deletions

49
.gitignore vendored Normal file
View 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
View 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
View 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
View File

@@ -0,0 +1,4 @@
pyautogui==0.9.54
pygetwindow==0.0.9
# 如果需要跨平台支持,可以添加以下库
# pynput==1.7.6