a
This commit is contained in:
+375
@@ -0,0 +1,375 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Cookie应急处理脚本
|
||||
当Cookie失效时,提供详细的恢复指南
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
from datetime import datetime
|
||||
import subprocess
|
||||
|
||||
class CookieEmergencyHandler:
|
||||
"""Cookie应急处理器"""
|
||||
|
||||
def __init__(self):
|
||||
self.cookie_file = os.path.expanduser("~/.xiaohongshu-cli/cookies.json")
|
||||
self.qqbot = None
|
||||
|
||||
# 尝试导入QQBot
|
||||
try:
|
||||
from qqbot_integration import QQBotIntegration
|
||||
self.qqbot = QQBotIntegration()
|
||||
except:
|
||||
print("⚠️ QQBot集成不可用")
|
||||
|
||||
def diagnose_cookie_issue(self):
|
||||
"""诊断Cookie问题"""
|
||||
print("🔍 诊断Cookie问题...")
|
||||
|
||||
issues = []
|
||||
|
||||
# 1. 检查文件是否存在
|
||||
if not os.path.exists(self.cookie_file):
|
||||
issues.append({
|
||||
'type': 'FILE_MISSING',
|
||||
'severity': 'CRITICAL',
|
||||
'message': 'Cookie文件不存在',
|
||||
'solution': '需要重新获取Cookie'
|
||||
})
|
||||
return issues
|
||||
|
||||
# 2. 检查文件权限
|
||||
if not os.access(self.cookie_file, os.R_OK):
|
||||
issues.append({
|
||||
'type': 'PERMISSION_DENIED',
|
||||
'severity': 'HIGH',
|
||||
'message': 'Cookie文件不可读',
|
||||
'solution': '检查文件权限: chmod 644 ~/.xiaohongshu-cli/cookies.json'
|
||||
})
|
||||
|
||||
# 3. 检查文件内容
|
||||
try:
|
||||
with open(self.cookie_file, 'r', encoding='utf-8') as f:
|
||||
cookies = json.load(f)
|
||||
|
||||
if not isinstance(cookies, dict):
|
||||
issues.append({
|
||||
'type': 'INVALID_FORMAT',
|
||||
'severity': 'HIGH',
|
||||
'message': 'Cookie文件格式错误',
|
||||
'solution': 'Cookie文件应该是JSON字典格式'
|
||||
})
|
||||
elif len(cookies) == 0:
|
||||
issues.append({
|
||||
'type': 'EMPTY_COOKIE',
|
||||
'severity': 'HIGH',
|
||||
'message': 'Cookie文件为空',
|
||||
'solution': '需要重新获取Cookie'
|
||||
})
|
||||
else:
|
||||
print(f"✅ Cookie文件格式正确,包含 {len(cookies)} 个Cookie")
|
||||
|
||||
# 检查关键Cookie
|
||||
key_cookies = ['a1', 'webId', 'web_session', 'x-user-id-creator.xiaohongshu.com']
|
||||
missing_keys = []
|
||||
|
||||
for key in key_cookies:
|
||||
if key not in cookies:
|
||||
missing_keys.append(key)
|
||||
|
||||
if missing_keys:
|
||||
issues.append({
|
||||
'type': 'MISSING_KEY_COOKIES',
|
||||
'severity': 'HIGH',
|
||||
'message': f'缺少关键Cookie: {", ".join(missing_keys)}',
|
||||
'solution': '这些Cookie对于登录至关重要,需要重新获取'
|
||||
})
|
||||
|
||||
except json.JSONDecodeError as e:
|
||||
issues.append({
|
||||
'type': 'JSON_PARSE_ERROR',
|
||||
'severity': 'HIGH',
|
||||
'message': f'JSON解析错误: {str(e)}',
|
||||
'solution': 'Cookie文件损坏,需要重新获取'
|
||||
})
|
||||
except Exception as e:
|
||||
issues.append({
|
||||
'type': 'UNKNOWN_ERROR',
|
||||
'severity': 'HIGH',
|
||||
'message': f'读取Cookie文件时出错: {str(e)}',
|
||||
'solution': '检查文件完整性'
|
||||
})
|
||||
|
||||
# 4. 测试Cookie有效性
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['xhs', 'status', '--json'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
issues.append({
|
||||
'type': 'XHS_COMMAND_FAILED',
|
||||
'severity': 'HIGH',
|
||||
'message': f'xhs命令执行失败: {result.stderr[:100]}',
|
||||
'solution': '检查xhs-cli安装和配置'
|
||||
})
|
||||
else:
|
||||
data = json.loads(result.stdout)
|
||||
if not data.get('ok') or not data.get('data', {}).get('authenticated'):
|
||||
issues.append({
|
||||
'type': 'COOKIE_INVALID',
|
||||
'severity': 'CRITICAL',
|
||||
'message': 'Cookie无效或已过期',
|
||||
'solution': '需要重新登录小红书获取新Cookie'
|
||||
})
|
||||
else:
|
||||
print(f"✅ Cookie验证通过,用户: {data['data']['user'].get('nickname')}")
|
||||
|
||||
except subprocess.TimeoutExpired:
|
||||
issues.append({
|
||||
'type': 'CHECK_TIMEOUT',
|
||||
'severity': 'MEDIUM',
|
||||
'message': 'Cookie检查超时',
|
||||
'solution': '网络问题或xhs-cli响应慢'
|
||||
})
|
||||
except Exception as e:
|
||||
issues.append({
|
||||
'type': 'CHECK_ERROR',
|
||||
'severity': 'HIGH',
|
||||
'message': f'Cookie检查出错: {str(e)}',
|
||||
'solution': '检查系统配置'
|
||||
})
|
||||
|
||||
return issues
|
||||
|
||||
def generate_recovery_guide(self, issues):
|
||||
"""生成恢复指南"""
|
||||
print("\n📋 生成恢复指南...")
|
||||
|
||||
guide = "🔧 小红书Cookie恢复指南\n"
|
||||
guide += "=" * 50 + "\n\n"
|
||||
guide += f"⏰ 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
||||
|
||||
# 问题摘要
|
||||
critical_count = sum(1 for issue in issues if issue['severity'] == 'CRITICAL')
|
||||
high_count = sum(1 for issue in issues if issue['severity'] == 'HIGH')
|
||||
|
||||
guide += f"📊 问题摘要:\n"
|
||||
guide += f" 严重问题: {critical_count} 个\n"
|
||||
guide += f" 高级问题: {high_count} 个\n"
|
||||
guide += f" 总问题数: {len(issues)} 个\n\n"
|
||||
|
||||
# 详细问题
|
||||
guide += "🔍 详细问题:\n"
|
||||
for i, issue in enumerate(issues, 1):
|
||||
emoji = "🔴" if issue['severity'] in ['CRITICAL', 'HIGH'] else "🟡"
|
||||
guide += f"{emoji} 问题 {i}: {issue['type']}\n"
|
||||
guide += f" 严重性: {issue['severity']}\n"
|
||||
guide += f" 描述: {issue['message']}\n"
|
||||
guide += f" 解决方案: {issue['solution']}\n\n"
|
||||
|
||||
# 恢复步骤
|
||||
guide += "🚀 恢复步骤:\n"
|
||||
guide += "1. 重新登录小红书\n"
|
||||
guide += " - 打开小红书网页版 (https://www.xiaohongshu.com)\n"
|
||||
guide += " - 使用账号密码登录\n"
|
||||
guide += " - 确保登录状态正常\n\n"
|
||||
|
||||
guide += "2. 导出Cookie\n"
|
||||
guide += " - 安装EditThisCookie浏览器插件\n"
|
||||
guide += " - 在小红书页面点击插件图标\n"
|
||||
guide += " - 点击'导出'按钮,保存为cookies.txt\n\n"
|
||||
|
||||
guide += "3. 导入新Cookie\n"
|
||||
guide += " cd ~/.nanobot/workspace/skills/xiaohongshu_integration\n"
|
||||
guide += " python3 cookie_manager.py import /path/to/cookies.txt --type editthis\n\n"
|
||||
|
||||
guide += "4. 验证Cookie\n"
|
||||
guide += " python3 cookie_manager.py check\n"
|
||||
guide += " python3 xiaohongshu_publisher.py check\n\n"
|
||||
|
||||
guide += "5. 测试发布\n"
|
||||
guide += " python3 xiaohongshu_publisher.py test\n\n"
|
||||
|
||||
# 快速命令
|
||||
guide += "⚡ 快速命令:\n"
|
||||
guide += " # 诊断问题\n"
|
||||
guide += " python3 cookie_emergency_handler.py diagnose\n\n"
|
||||
guide += " # 导入Cookie\n"
|
||||
guide += " python3 cookie_manager.py import cookies.txt\n\n"
|
||||
guide += " # 检查状态\n"
|
||||
guide += " python3 cookie_manager.py check\n\n"
|
||||
|
||||
# 文件位置
|
||||
guide += "📁 文件位置:\n"
|
||||
guide += " Cookie文件: ~/.xiaohongshu-cli/cookies.json\n"
|
||||
guide += " 备份目录: ~/.xiaohongshu-cli/backups/\n"
|
||||
guide += " 技能目录: ~/.nanobot/workspace/skills/xiaohongshu_integration/\n"
|
||||
|
||||
return guide
|
||||
|
||||
def send_emergency_alert(self, issues):
|
||||
"""发送紧急告警"""
|
||||
if not self.qqbot:
|
||||
print("❌ QQBot不可用,无法发送紧急告警")
|
||||
return False
|
||||
|
||||
print("🔔 发送紧急告警到QQBot...")
|
||||
|
||||
# 生成告警消息
|
||||
critical_issues = [i for i in issues if i['severity'] in ['CRITICAL', 'HIGH']]
|
||||
|
||||
if not critical_issues:
|
||||
print("✅ 无严重问题,无需发送紧急告警")
|
||||
return True
|
||||
|
||||
alert_message = f"发现 {len(critical_issues)} 个严重Cookie问题,需要立即处理!"
|
||||
|
||||
# 构建详细信息
|
||||
cookie_info = {
|
||||
'问题数量': f'{len(critical_issues)} 个严重问题',
|
||||
'最严重问题': critical_issues[0]['type'],
|
||||
'生成时间': datetime.now().strftime('%H:%M:%S'),
|
||||
'状态': '需要立即处理'
|
||||
}
|
||||
|
||||
# 发送告警
|
||||
return self.qqbot.send_cookie_alert('COOKIE_EXPIRED', alert_message, cookie_info)
|
||||
|
||||
def create_backup(self):
|
||||
"""创建Cookie备份"""
|
||||
print("💾 创建Cookie备份...")
|
||||
|
||||
if not os.path.exists(self.cookie_file):
|
||||
print("❌ Cookie文件不存在,无法备份")
|
||||
return False
|
||||
|
||||
try:
|
||||
# 使用cookie_manager备份
|
||||
from cookie_manager import XiaohongshuCookieManager
|
||||
manager = XiaohongshuCookieManager()
|
||||
backup_file = manager.backup_current_cookies()
|
||||
|
||||
if backup_file:
|
||||
print(f"✅ Cookie备份成功: {backup_file}")
|
||||
return backup_file
|
||||
else:
|
||||
print("❌ Cookie备份失败")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 备份失败: {e}")
|
||||
|
||||
# 手动备份
|
||||
backup_dir = os.path.expanduser("~/.xiaohongshu-cli/emergency_backup")
|
||||
os.makedirs(backup_dir, exist_ok=True)
|
||||
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_file = os.path.join(backup_dir, f"cookies_emergency_{timestamp}.json")
|
||||
|
||||
import shutil
|
||||
shutil.copy2(self.cookie_file, backup_file)
|
||||
|
||||
print(f"✅ 手动备份成功: {backup_file}")
|
||||
return backup_file
|
||||
|
||||
def emergency_recovery(self):
|
||||
"""应急恢复流程"""
|
||||
print("🚨 执行应急恢复流程...")
|
||||
|
||||
# 1. 诊断问题
|
||||
issues = self.diagnose_cookie_issue()
|
||||
|
||||
# 2. 创建备份
|
||||
backup_file = self.create_backup()
|
||||
|
||||
# 3. 生成恢复指南
|
||||
guide = self.generate_recovery_guide(issues)
|
||||
|
||||
# 4. 保存指南到文件
|
||||
guide_file = f"/tmp/xiaohongshu_recovery_guide_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
|
||||
with open(guide_file, 'w', encoding='utf-8') as f:
|
||||
f.write(guide)
|
||||
|
||||
print(f"✅ 恢复指南已保存: {guide_file}")
|
||||
|
||||
# 5. 发送紧急告警
|
||||
if issues:
|
||||
self.send_emergency_alert(issues)
|
||||
|
||||
# 6. 显示指南
|
||||
print("\n" + "=" * 70)
|
||||
print("应急恢复指南")
|
||||
print("=" * 70)
|
||||
print(guide[:500] + "...")
|
||||
print(f"\n完整指南: {guide_file}")
|
||||
|
||||
return guide_file
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Cookie应急处理器')
|
||||
subparsers = parser.add_subparsers(dest='command', help='命令')
|
||||
|
||||
# diagnose命令
|
||||
subparsers.add_parser('diagnose', help='诊断Cookie问题')
|
||||
|
||||
# recover命令
|
||||
subparsers.add_parser('recover', help='执行应急恢复')
|
||||
|
||||
# backup命令
|
||||
subparsers.add_parser('backup', help='创建Cookie备份')
|
||||
|
||||
# guide命令
|
||||
subparsers.add_parser('guide', help='生成恢复指南')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
handler = CookieEmergencyHandler()
|
||||
|
||||
if args.command == 'diagnose':
|
||||
issues = handler.diagnose_cookie_issue()
|
||||
if issues:
|
||||
print(f"🔍 发现 {len(issues)} 个问题:")
|
||||
for issue in issues:
|
||||
print(f" {issue['severity']}: {issue['type']} - {issue['message']}")
|
||||
else:
|
||||
print("✅ 未发现问题,Cookie状态正常")
|
||||
|
||||
elif args.command == 'recover':
|
||||
handler.emergency_recovery()
|
||||
|
||||
elif args.command == 'backup':
|
||||
handler.create_backup()
|
||||
|
||||
elif args.command == 'guide':
|
||||
# 模拟一些问题
|
||||
test_issues = [
|
||||
{
|
||||
'type': 'COOKIE_EXPIRED',
|
||||
'severity': 'CRITICAL',
|
||||
'message': 'Cookie已过期',
|
||||
'solution': '重新登录获取新Cookie'
|
||||
},
|
||||
{
|
||||
'type': 'MISSING_KEY_COOKIES',
|
||||
'severity': 'HIGH',
|
||||
'message': '缺少关键Cookie: a1, webId',
|
||||
'solution': '需要完整的Cookie集合'
|
||||
}
|
||||
]
|
||||
guide = handler.generate_recovery_guide(test_issues)
|
||||
print(guide)
|
||||
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user