Files
nanocode/skills/xiaohongshu_integration/cookie_emergency_handler.py
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

375 lines
13 KiB
Python
Executable File

#!/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()