Files
ai_wht_wechat/backend/test_cookie_inject.py
2026-01-06 19:36:42 +08:00

399 lines
13 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Cookie注入测试脚本
使用Playwright注入Cookie并验证其有效性
支持跳转到创作者中心或小红书首页
"""
import asyncio
import sys
import json
from pathlib import Path
from playwright.async_api import async_playwright
from typing import Optional, List, Dict, Any
class CookieInjector:
"""Cookie注入器"""
def __init__(self, headless: bool = False):
"""
初始化Cookie注入器
Args:
headless: 是否使用无头模式False可以看到浏览器界面
"""
self.headless = headless
self.playwright = None
self.browser = None
self.context = None
self.page = None
async def init_browser(self):
"""初始化浏览器"""
try:
print("正在启动浏览器...")
# Windows环境下设置事件循环策略
if sys.platform == 'win32':
try:
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
except Exception as e:
print(f"警告: 设置事件循环策略失败: {str(e)}")
self.playwright = await async_playwright().start()
# 启动浏览器
self.browser = await self.playwright.chromium.launch(
headless=self.headless,
args=['--disable-blink-features=AutomationControlled']
)
# 创建浏览器上下文
self.context = await self.browser.new_context(
viewport={'width': 1280, 'height': 720},
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'
)
# 创建新页面
self.page = await self.context.new_page()
print("浏览器初始化成功")
except Exception as e:
print(f"浏览器初始化失败: {str(e)}")
raise
async def inject_cookies(self, cookies: List[Dict[str, Any]]) -> bool:
"""
注入Cookie
Args:
cookies: Cookie列表
Returns:
是否注入成功
"""
try:
if not self.context:
await self.init_browser()
print(f"正在注入 {len(cookies)} 个Cookie...")
# 注入Cookie到浏览器上下文
await self.context.add_cookies(cookies)
print("Cookie注入成功")
return True
except Exception as e:
print(f"Cookie注入失败: {str(e)}")
return False
async def verify_and_navigate(self, target_page: str = 'creator') -> Dict[str, Any]:
"""
验证Cookie并跳转到指定页面
Args:
target_page: 目标页面类型 ('creator''home')
Returns:
验证结果字典
"""
try:
if not self.page:
return {"success": False, "error": "浏览器未初始化"}
# 确定目标URL
urls = {
'creator': 'https://creator.xiaohongshu.com',
'home': 'https://www.xiaohongshu.com'
}
target_url = urls.get(target_page, urls['creator'])
page_name = '创作者中心' if target_page == 'creator' else '小红书首页'
print(f"\n正在访问{page_name}: {target_url}")
# 访问目标页面
await self.page.goto(target_url, wait_until='networkidle', timeout=30000)
await asyncio.sleep(2) # 等待页面完全加载
# 获取当前URL和标题
current_url = self.page.url
title = await self.page.title()
print(f"当前URL: {current_url}")
print(f"页面标题: {title}")
# 检查是否被重定向到登录页
is_logged_in = 'login' not in current_url.lower()
if is_logged_in:
print("Cookie验证成功已登录状态")
# 尝试获取用户信息
try:
# 等待用户相关元素出现(如头像、用户名等)
await self.page.wait_for_selector('[class*="avatar"], [class*="user"]', timeout=5000)
print("检测到用户信息元素,确认登录成功")
except Exception:
print("未检测到明显的用户信息元素,但未跳转到登录页")
return {
"success": True,
"message": f"Cookie有效已成功访问{page_name}",
"url": current_url,
"title": title,
"logged_in": True
}
else:
print("Cookie可能已失效页面跳转到登录页")
return {
"success": False,
"error": "Cookie已失效或无效页面跳转到登录页",
"url": current_url,
"title": title,
"logged_in": False
}
except Exception as e:
print(f"验证过程异常: {str(e)}")
import traceback
traceback.print_exc()
return {
"success": False,
"error": f"验证过程异常: {str(e)}"
}
async def keep_browser_open(self, duration: int = 60):
"""
保持浏览器打开一段时间,方便观察
Args:
duration: 保持打开的秒数0表示永久打开直到手动关闭
"""
try:
if duration == 0:
print("\n浏览器将保持打开,按 Ctrl+C 关闭...")
try:
while True:
await asyncio.sleep(1)
except KeyboardInterrupt:
print("\n用户中断,准备关闭浏览器...")
else:
print(f"\n浏览器将保持打开 {duration} 秒...")
await asyncio.sleep(duration)
print("时间到,准备关闭浏览器...")
except Exception as e:
print(f"保持浏览器异常: {str(e)}")
async def close_browser(self):
"""关闭浏览器"""
try:
print("\n正在关闭浏览器...")
if self.page:
await self.page.close()
if self.context:
await self.context.close()
if self.browser:
await self.browser.close()
if self.playwright:
await self.playwright.stop()
print("浏览器已关闭")
except Exception as e:
print(f"关闭浏览器异常: {str(e)}")
def load_cookies_from_file(file_path: str) -> Optional[List[Dict[str, Any]]]:
"""
从文件加载Cookie
Args:
file_path: Cookie文件路径
Returns:
Cookie列表失败返回None
"""
try:
cookie_file = Path(file_path)
if not cookie_file.exists():
print(f"Cookie文件不存在: {file_path}")
return None
with open(cookie_file, 'r', encoding='utf-8') as f:
cookies = json.load(f)
if not isinstance(cookies, list):
print("Cookie格式错误必须是数组")
return None
if len(cookies) == 0:
print("Cookie数组为空")
return None
# 验证每个Cookie必须有name和value
for cookie in cookies:
if not cookie.get('name') or not cookie.get('value'):
print(f"Cookie格式错误缺少name或value字段")
return None
print(f"成功加载 {len(cookies)} 个Cookie")
return cookies
except json.JSONDecodeError as e:
print(f"Cookie文件JSON解析失败: {str(e)}")
return None
except Exception as e:
print(f"加载Cookie文件失败: {str(e)}")
return None
async def test_cookie_inject(
cookies_source: str,
target_page: str = 'creator',
headless: bool = False,
keep_open: int = 0
):
"""
测试Cookie注入
Args:
cookies_source: Cookie来源文件路径或JSON字符串
target_page: 目标页面 ('creator''home')
headless: 是否使用无头模式
keep_open: 保持浏览器打开的秒数0表示永久打开
"""
print("="*60)
print("Cookie注入并验证测试")
print("="*60)
# 加载Cookie
cookies = None
# 尝试作为文件路径加载
if Path(cookies_source).exists():
print(f"\n从文件加载Cookie: {cookies_source}")
cookies = load_cookies_from_file(cookies_source)
else:
# 尝试作为JSON字符串解析
try:
print("\n尝试解析Cookie JSON字符串...")
cookies = json.loads(cookies_source)
if isinstance(cookies, list) and len(cookies) > 0:
print(f"成功解析 {len(cookies)} 个Cookie")
except Exception as e:
print(f"Cookie解析失败: {str(e)}")
if not cookies:
print("\n加载Cookie失败请检查输入")
return
# 创建注入器
injector = CookieInjector(headless=headless)
try:
# 初始化浏览器
await injector.init_browser()
# 注入Cookie
inject_success = await injector.inject_cookies(cookies)
if not inject_success:
print("\nCookie注入失败")
return
# 验证并跳转
result = await injector.verify_and_navigate(target_page)
print("\n" + "="*60)
print("验证结果")
print("="*60)
if result.get('success'):
print(f"状态: 成功")
print(f"消息: {result.get('message')}")
print(f"URL: {result.get('url')}")
print(f"标题: {result.get('title')}")
print(f"登录状态: {'已登录' if result.get('logged_in') else '未登录'}")
else:
print(f"状态: 失败")
print(f"错误: {result.get('error')}")
if result.get('url'):
print(f"当前URL: {result.get('url')}")
# 保持浏览器打开
if keep_open >= 0:
await injector.keep_browser_open(keep_open)
except KeyboardInterrupt:
print("\n\n用户中断测试")
except Exception as e:
print(f"\n测试过程异常: {str(e)}")
import traceback
traceback.print_exc()
finally:
await injector.close_browser()
print("\n" + "="*60)
print("测试完成")
print("="*60)
async def main():
"""主函数"""
print("="*60)
print("小红书Cookie注入测试工具")
print("="*60)
print("\n功能说明:")
print("1. 注入Cookie到浏览器")
print("2. 验证Cookie有效性")
print("3. 跳转到指定页面(创作者中心/小红书首页)")
print("\n" + "="*60)
# 输入Cookie来源
print("\n请输入Cookie来源")
print("1. 输入Cookie文件路径如: cookies.json")
print("2. 直接粘贴JSON格式的Cookie")
cookies_source = input("\nCookie来源: ").strip()
if not cookies_source:
print("Cookie来源不能为空")
return
# 选择目标页面
print("\n请选择目标页面:")
print("1. 创作者中心creator.xiaohongshu.com")
print("2. 小红书首页www.xiaohongshu.com")
page_choice = input("\n选择 (1 或 2, 默认为 1): ").strip()
target_page = 'home' if page_choice == '2' else 'creator'
# 选择浏览器模式
headless_choice = input("\n是否使用无头模式?(y/n, 默认为 n): ").strip().lower()
headless = headless_choice == 'y'
# 选择保持打开时间
keep_open_input = input("\n保持浏览器打开时间0表示直到手动关闭默认60: ").strip()
try:
keep_open = int(keep_open_input) if keep_open_input else 60
except ValueError:
keep_open = 60
# 执行测试
await test_cookie_inject(
cookies_source=cookies_source,
target_page=target_page,
headless=headless,
keep_open=keep_open
)
if __name__ == "__main__":
# Windows环境下设置事件循环策略
if sys.platform == 'win32':
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
# 运行测试
asyncio.run(main())