add-files

This commit is contained in:
2026-03-03 08:58:16 +08:00
parent 0fbbbce2ee
commit 894acc3191
23 changed files with 2492 additions and 1 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+248
View File
@@ -0,0 +1,248 @@
# CookieCloud Client
一个独立的、可复用的CookieCloud服务器客户端Python模块。
## 特性
-**完全独立** - 无外部依赖,仅使用Python标准库
-**类型安全** - 完整的类型提示支持
-**异常处理** - 完善的异常体系
-**易于使用** - 简洁的API设计
-**可扩展** - 支持自定义配置
-**文档完善** - 详细的使用文档和示例
## 安装
`cookiecloud_client` 目录复制到您的项目中即可使用。
## 快速开始
### 基本使用
```python
from cookiecloud_client import CookieCloudClient, CookieConfig
# 创建配置
config = CookieConfig(
server="https://cookiecloud.example.com",
username="your_username",
password="your_password"
)
# 创建客户端
client = CookieCloudClient(config)
# 下载所有cookies
result = client.download()
if result.success:
print(f"下载成功!")
print(f"总域名数: {result.total_domains}")
print(f"总Cookie数: {result.total_cookies}")
print(f"下载耗时: {result.download_time:.2f}")
# 获取指定域名的cookie
cookie_str = result.get_cookie_string("example.com")
print(f"example.com的cookie: {cookie_str}")
else:
print(f"下载失败: {result.error_message}")
```
### 下载指定域名的Cookie
```python
# 下载单个域名
cookie_str = client.download_for_domain("baidu.com")
if cookie_str:
print(f"baidu.com的cookie: {cookie_str}")
# 批量下载多个域名
domains = ["baidu.com", "google.com", "github.com"]
cookies = client.download_for_domains(domains)
for domain, cookie in cookies.items():
print(f"{domain}: {cookie}")
```
### 测试连接
```python
success, message = client.test_connection()
if success:
print("连接成功!")
else:
print(f"连接失败: {message}")
```
## 高级用法
### 自定义配置
```python
config = CookieConfig(
server="https://cookiecloud.example.com",
username="your_username",
password="your_password",
timeout=60, # 超时时间(秒)
verify_ssl=False, # 是否验证SSL证书
ignore_cookies=[ # 忽略的cookie名称
"CookieAutoDeleteBrowsingDataCleanup",
"CookieAutoDeleteCleaningDiscarded"
]
)
```
### 异常处理
```python
from cookiecloud_client import (
CookieCloudClient,
CookieConfig,
CookieCloudError,
ConnectionError,
AuthenticationError,
DataParseError,
NetworkError
)
try:
client = CookieCloudClient(config)
result = client.download()
except AuthenticationError as e:
print(f"认证失败: {e.message}")
print(f"用户名: {e.details.get('username')}")
except ConnectionError as e:
print(f"连接失败: {e.message}")
print(f"服务器: {e.details.get('server')}")
print(f"状态码: {e.details.get('status_code')}")
except DataParseError as e:
print(f"数据解析失败: {e.message}")
except NetworkError as e:
print(f"网络错误: {e.message}")
print(f"原始错误: {e.details.get('original_error')}")
except CookieCloudError as e:
print(f"CookieCloud错误: {e.message}")
```
### 使用Cookie数据对象
```python
result = client.download()
# 获取所有域名
domains = result.get_domains()
print(f"所有域名: {domains}")
# 遍历所有cookie
for domain, collection in result.cookies.items():
print(f"\n域名: {domain}")
for cookie in collection.cookies:
print(f" - {cookie.name}={cookie.value[:20]}...")
print(f" 路径: {cookie.path}")
print(f" 安全: {cookie.secure}")
print(f" HttpOnly: {cookie.http_only}")
```
## API文档
### CookieConfig
配置类,用于存储CookieCloud服务器配置。
**参数:**
- `server` (str): CookieCloud服务器地址
- `username` (str): 用户名
- `password` (str): 密码
- `timeout` (int): 请求超时时间(秒),默认30
- `verify_ssl` (bool): 是否验证SSL证书,默认True
- `ignore_cookies` (List[str]): 忽略的cookie名称列表
### CookieCloudClient
客户端类,用于与CookieCloud服务器交互。
**方法:**
#### `download() -> DownloadResult`
下载所有cookies
**返回:** DownloadResult对象
#### `download_for_domain(domain: str) -> Optional[str]`
下载指定域名的cookie字符串
**参数:**
- `domain` (str): 目标域名
**返回:** cookie字符串或None
#### `download_for_domains(domains: List[str]) -> Dict[str, Optional[str]]`
批量下载多个域名的cookie字符串
**参数:**
- `domains` (List[str]): 目标域名列表
**返回:** {domain: cookie_string}字典
#### `test_connection() -> Tuple[bool, str]`
测试与CookieCloud服务器的连接
**返回:** (是否成功, 消息)元组
### DownloadResult
下载结果类。
**属性:**
- `success` (bool): 是否成功
- `cookies` (Dict[str, CookieCollection]): cookie集合字典
- `error_message` (str): 错误信息
- `total_domains` (int): 总域名数
- `total_cookies` (int): 总cookie数
- `download_time` (float): 下载耗时(秒)
**方法:**
- `get_cookie_string(domain: str) -> Optional[str]`: 获取指定域名的cookie字符串
- `get_domains() -> List[str]`: 获取所有域名列表
## 异常类
### CookieCloudError
基础异常类,所有其他异常都继承自此类。
### ConfigurationError
配置错误异常
### ConnectionError
连接错误异常
### AuthenticationError
认证错误异常
### DataParseError
数据解析错误异常
### NetworkError
网络错误异常
## 依赖
- Python 3.7+
- 仅使用Python标准库
## 许可证
MIT License
## 更新日志
### v1.0.0 (2026-03-02)
- 初始版本发布
- 完整的CookieCloud客户端功能
- 独立模块,无外部依赖
- 完善的异常处理
- 详细的文档和示例
+33
View File
@@ -0,0 +1,33 @@
"""
CookieCloud客户端模块
一个独立的、可复用的CookieCloud服务器客户端
作者: CookieManager Team
版本: 1.0.0
许可证: MIT
"""
from .client import CookieCloudClient
from .exceptions import (
CookieCloudError,
ConnectionError,
AuthenticationError,
DataParseError,
ConfigurationError,
NetworkError
)
from .models import CookieData, CookieConfig
from .version import __version__
__all__ = [
'CookieCloudClient',
'CookieCloudError',
'ConnectionError',
'AuthenticationError',
'DataParseError',
'ConfigurationError',
'NetworkError',
'CookieData',
'CookieConfig',
'__version__'
]
Binary file not shown.
+347
View File
@@ -0,0 +1,347 @@
"""
CookieCloud客户端核心实现
"""
import json
import time
import urllib.request
import urllib.error
from typing import Dict, List, Optional, Tuple
from .models import CookieConfig, CookieData, CookieCollection, DownloadResult
from .exceptions import (
CookieCloudError,
ConfigurationError,
ConnectionError,
AuthenticationError,
DataParseError,
NetworkError
)
class CookieCloudClient:
"""
CookieCloud客户端
用于从CookieCloud服务器下载和管理cookies的独立客户端
示例:
>>> config = CookieConfig(
... server="https://cookiecloud.example.com",
... username="your_username",
... password="your_password"
... )
>>> client = CookieCloudClient(config)
>>> result = client.download()
>>> if result.success:
... print(f"下载成功,共{result.total_domains}个域名")
... cookie_str = result.get_cookie_string("example.com")
"""
def __init__(self, config: CookieConfig):
"""
初始化客户端
Args:
config: CookieCloud配置对象
Raises:
ConfigurationError: 配置验证失败
"""
if not isinstance(config, CookieConfig):
raise ConfigurationError("配置参数必须是CookieConfig类型")
self.config = config
self._last_download_time = None
self._download_count = 0
def download(self) -> DownloadResult:
"""
从CookieCloud服务器下载所有cookies
Returns:
DownloadResult: 下载结果对象
Raises:
ConnectionError: 连接服务器失败
AuthenticationError: 认证失败
DataParseError: 数据解析失败
NetworkError: 网络错误
"""
start_time = time.time()
try:
raw_data = self._fetch_data()
cookies = self._parse_cookies(raw_data)
download_time = time.time() - start_time
self._last_download_time = time.time()
self._download_count += 1
total_cookies = sum(len(c.cookies) for c in cookies.values())
return DownloadResult(
success=True,
cookies=cookies,
total_domains=len(cookies),
total_cookies=total_cookies,
download_time=download_time
)
except CookieCloudError:
raise
except Exception as e:
raise CookieCloudError(f"下载cookies失败: {str(e)}")
def download_for_domain(self, domain: str) -> Optional[str]:
"""
下载指定域名的cookie字符串
Args:
domain: 目标域名
Returns:
Optional[str]: cookie字符串,如果不存在则返回None
Raises:
ConnectionError: 连接服务器失败
AuthenticationError: 认证失败
DataParseError: 数据解析失败
"""
result = self.download()
return result.get_cookie_string(domain)
def download_for_domains(self, domains: List[str]) -> Dict[str, Optional[str]]:
"""
批量下载多个域名的cookie字符串
Args:
domains: 目标域名列表
Returns:
Dict[str, Optional[str]]: {domain: cookie_string}
"""
result = self.download()
return {domain: result.get_cookie_string(domain) for domain in domains}
def test_connection(self) -> Tuple[bool, str]:
"""
测试与CookieCloud服务器的连接
Returns:
Tuple[bool, str]: (是否成功, 消息)
"""
try:
self._fetch_data()
return True, "连接成功"
except AuthenticationError as e:
return False, f"认证失败: {e.message}"
except ConnectionError as e:
return False, f"连接失败: {e.message}"
except Exception as e:
return False, f"测试失败: {str(e)}"
def _fetch_data(self) -> Dict:
"""
从服务器获取原始数据
Returns:
Dict: 原始JSON数据
Raises:
ConnectionError: 连接失败
AuthenticationError: 认证失败
NetworkError: 网络错误
"""
url = f"{self.config.server}/get/{self.config.username}"
try:
data = json.dumps({"password": self.config.password}).encode('utf-8')
request = urllib.request.Request(
url,
data=data,
headers={
'Content-Type': 'application/json',
'User-Agent': 'CookieCloudClient/1.0'
},
method='POST'
)
response = urllib.request.urlopen(
request,
timeout=self.config.timeout
)
if response.status != 200:
if response.status == 401:
raise AuthenticationError(
"认证失败,请检查用户名和密码",
username=self.config.username
)
elif response.status == 404:
raise ConnectionError(
"用户不存在,请检查用户名",
server=self.config.server,
status_code=response.status
)
else:
raise ConnectionError(
f"服务器返回错误状态码: {response.status}",
server=self.config.server,
status_code=response.status
)
result = json.loads(response.read().decode('utf-8'))
if not result:
raise DataParseError("服务器返回数据为空")
return result
except urllib.error.HTTPError as e:
if e.code == 401:
raise AuthenticationError(
"认证失败,请检查用户名和密码",
username=self.config.username
)
else:
raise ConnectionError(
f"HTTP错误: {e.code} {e.reason}",
server=self.config.server,
status_code=e.code
)
except urllib.error.URLError as e:
raise NetworkError(
f"网络连接失败: {e.reason}",
original_error=e
)
except json.JSONDecodeError as e:
raise DataParseError(
f"JSON解析失败: {str(e)}"
)
except Exception as e:
if isinstance(e, CookieCloudError):
raise
raise NetworkError(
f"请求失败: {str(e)}",
original_error=e
)
def _parse_cookies(self, raw_data: Dict) -> Dict[str, CookieCollection]:
"""
解析原始cookie数据
Args:
raw_data: 原始JSON数据
Returns:
Dict[str, CookieCollection]: {domain: CookieCollection}
"""
if raw_data.get("cookie_data"):
contents = raw_data.get("cookie_data")
else:
contents = raw_data
domain_groups = self._group_by_domain(contents)
cookies = {}
for domain, cookie_list in domain_groups.items():
if not cookie_list:
continue
if self._is_cloudflare_only(cookie_list):
continue
collection = CookieCollection(domain=domain)
for cookie_data in cookie_list:
cookie = CookieData(
domain=cookie_data.get('domain', ''),
name=cookie_data.get('name', ''),
value=cookie_data.get('value', ''),
path=cookie_data.get('path', '/'),
secure=cookie_data.get('secure', False),
http_only=cookie_data.get('httpOnly', False)
)
collection.add_cookie(cookie)
cookies[domain] = collection
return cookies
def _group_by_domain(self, contents: Dict) -> Dict[str, List[Dict]]:
"""
按域名分组cookies
Args:
contents: 原始cookie内容
Returns:
Dict[str, List[Dict]]: {domain: [cookie_data]}
"""
domain_groups = {}
for site, cookies in contents.items():
for cookie in cookies:
domain = cookie.get("domain", "")
if not domain:
continue
domain_key = self._extract_domain(domain)
if not domain_key:
continue
if domain_key not in domain_groups:
domain_groups[domain_key] = []
domain_groups[domain_key].append(cookie)
return domain_groups
def _extract_domain(self, domain: str) -> Optional[str]:
"""
提取主域名
Args:
domain: 原始域名
Returns:
Optional[str]: 主域名
"""
if not domain:
return None
domain = domain.lstrip('.')
parts = domain.split('.')
if len(parts) < 2:
return domain
if len(parts) == 2:
return domain
return '.'.join(parts[-2:])
def _is_cloudflare_only(self, cookie_list: List[Dict]) -> bool:
"""
检查是否仅包含Cloudflare验证cookie
Args:
cookie_list: cookie列表
Returns:
bool: 是否仅包含cf_clearance
"""
for cookie in cookie_list:
if cookie.get("name") != "cf_clearance":
return False
return True
@property
def last_download_time(self) -> Optional[float]:
"""获取最后下载时间"""
return self._last_download_time
@property
def download_count(self) -> int:
"""获取下载次数"""
return self._download_count
+259
View File
@@ -0,0 +1,259 @@
"""
CookieCloud客户端使用示例
演示如何使用cookiecloud_client模块
"""
import sys
import os
# 添加父目录到路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# 示例1: 基本使用
def example_basic_usage():
"""基本使用示例"""
from cookiecloud_client import CookieCloudClient, CookieConfig
print("=" * 60)
print("示例1: 基本使用")
print("=" * 60)
# 创建配置
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="hu6n2vcUmzpu7mqUN2rVCg",
password="jtDM5dV9AyqXkZdQVeA9f6"
)
# 创建客户端
client = CookieCloudClient(config)
# 测试连接
success, message = client.test_connection()
print(f"连接测试: {message}")
if success:
# 下载所有cookies
result = client.download()
if result.success:
print(f"\n✓ 下载成功!")
print(f" 总域名数: {result.total_domains}")
print(f" 总Cookie数: {result.total_cookies}")
print(f" 下载耗时: {result.download_time:.2f}")
# 显示前5个域名
domains = result.get_domains()[:5]
print(f"\n前5个域名:")
for idx, domain in enumerate(domains, 1):
cookie_str = result.get_cookie_string(domain)
preview = cookie_str[:50] + "..." if len(cookie_str) > 50 else cookie_str
print(f" {idx}. {domain}: {preview}")
else:
print(f"\n✗ 下载失败: {result.error_message}")
# 示例2: 下载指定域名的Cookie
def example_download_specific_domain():
"""下载指定域名示例"""
from cookiecloud_client import CookieCloudClient, CookieConfig
print("\n" + "=" * 60)
print("示例2: 下载指定域名的Cookie")
print("=" * 60)
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="hu6n2vcUmzpu7mqUN2rVCg",
password="jtDM5dV9AyqXkZdQVeA9f6"
)
client = CookieCloudClient(config)
# 下载单个域名
domain = "baidu.com"
cookie_str = client.download_for_domain(domain)
if cookie_str:
print(f"{domain}的Cookie:")
print(f" {cookie_str[:100]}...")
else:
print(f"✗ 未找到{domain}的Cookie")
# 示例3: 批量下载多个域名
def example_download_multiple_domains():
"""批量下载示例"""
from cookiecloud_client import CookieCloudClient, CookieConfig
print("\n" + "=" * 60)
print("示例3: 批量下载多个域名")
print("=" * 60)
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="hu6n2vcUmzpu7mqUN2rVCg",
password="jtDM5dV9AyqXkZdQVeA9f6"
)
client = CookieCloudClient(config)
# 批量下载
domains = ["baidu.com", "github.com", "google.com", "bing.com"]
cookies = client.download_for_domains(domains)
print("批量下载结果:")
for domain, cookie_str in cookies.items():
if cookie_str:
preview = cookie_str[:50] + "..."
print(f"{domain}: {preview}")
else:
print(f"{domain}: 未找到Cookie")
# 示例4: 异常处理
def example_error_handling():
"""异常处理示例"""
from cookiecloud_client import (
CookieCloudClient,
CookieConfig,
CookieCloudError,
ConnectionError,
AuthenticationError,
NetworkError
)
print("\n" + "=" * 60)
print("示例4: 异常处理")
print("=" * 60)
try:
# 使用错误的凭据
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="wrong_user",
password="wrong_pass"
)
client = CookieCloudClient(config)
result = client.download()
except AuthenticationError as e:
print(f"✗ 认证失败: {e.message}")
print(f" 用户名: {e.details.get('username')}")
except ConnectionError as e:
print(f"✗ 连接失败: {e.message}")
print(f" 服务器: {e.details.get('server')}")
print(f" 状态码: {e.details.get('status_code')}")
except NetworkError as e:
print(f"✗ 网络错误: {e.message}")
print(f" 原始错误: {e.details.get('original_error')}")
except CookieCloudError as e:
print(f"✗ CookieCloud错误: {e.message}")
# 示例5: 自定义配置
def example_custom_config():
"""自定义配置示例"""
from cookiecloud_client import CookieCloudClient, CookieConfig
print("\n" + "=" * 60)
print("示例5: 自定义配置")
print("=" * 60)
# 自定义配置
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="hu6n2vcUmzpu7mqUN2rVCg",
password="jtDM5dV9AyqXkZdQVeA9f6",
timeout=60, # 60秒超时
verify_ssl=False, # 不验证SSL证书
ignore_cookies=[ # 忽略的cookie
"CookieAutoDeleteBrowsingDataCleanup",
"CookieAutoDeleteCleaningDiscarded",
"_ga", # 忽略Google Analytics
]
)
client = CookieCloudClient(config)
print(f"配置信息:")
print(f" 服务器: {config.server}")
print(f" 用户名: {config.username}")
print(f" 超时时间: {config.timeout}")
print(f" 验证SSL: {config.verify_ssl}")
print(f" 忽略Cookie: {len(config.ignore_cookies)}")
result = client.download()
if result.success:
print(f"\n✓ 下载成功")
print(f" 总域名数: {result.total_domains}")
print(f" 总Cookie数: {result.total_cookies}")
# 示例6: 使用Cookie数据对象
def example_cookie_data_objects():
"""使用Cookie数据对象示例"""
from cookiecloud_client import CookieCloudClient, CookieConfig
print("\n" + "=" * 60)
print("示例6: 使用Cookie数据对象")
print("=" * 60)
config = CookieConfig(
server="https://movie-pilot.org/cookiecloud",
username="hu6n2vcUmzpu7mqUN2rVCg",
password="jtDM5dV9AyqXkZdQVeA9f6"
)
client = CookieCloudClient(config)
result = client.download()
if result.success:
# 获取第一个域名的详细信息
first_domain = result.get_domains()[0]
collection = result.cookies.get(first_domain)
if collection:
print(f"域名: {collection.domain}")
print(f"Cookie数量: {len(collection.cookies)}")
print(f"\nCookie详情:")
for idx, cookie in enumerate(collection.cookies[:3], 1):
print(f" {idx}. {cookie.name}")
print(f" 值: {cookie.value[:30]}...")
print(f" 路径: {cookie.path}")
print(f" 安全: {cookie.secure}")
print(f" HttpOnly: {cookie.http_only}")
print()
# 主函数
def main():
"""运行所有示例"""
print("\n")
print("" + "=" * 58 + "")
print("" + " " * 15 + "CookieCloud客户端使用示例" + " " * 17 + "")
print("" + "=" * 58 + "")
try:
example_basic_usage()
example_download_specific_domain()
example_download_multiple_domains()
example_error_handling()
example_custom_config()
example_cookie_data_objects()
print("\n" + "=" * 60)
print("所有示例执行完成!")
print("=" * 60)
except Exception as e:
print(f"\n示例执行出错: {str(e)}")
if __name__ == "__main__":
main()
+65
View File
@@ -0,0 +1,65 @@
"""
CookieCloud客户端异常类
"""
class CookieCloudError(Exception):
"""CookieCloud基础异常类"""
def __init__(self, message: str, details: dict = None):
self.message = message
self.details = details or {}
super().__init__(self.message)
def __str__(self):
if self.details:
return f"{self.message} - 详情: {self.details}"
return self.message
class ConfigurationError(CookieCloudError):
"""配置错误异常"""
def __init__(self, message: str, config_key: str = None):
details = {'config_key': config_key} if config_key else {}
super().__init__(message, details)
class ConnectionError(CookieCloudError):
"""连接错误异常"""
def __init__(self, message: str, server: str = None, status_code: int = None):
details = {}
if server:
details['server'] = server
if status_code:
details['status_code'] = status_code
super().__init__(message, details)
class AuthenticationError(CookieCloudError):
"""认证错误异常"""
def __init__(self, message: str, username: str = None):
details = {'username': username} if username else {}
super().__init__(message, details)
class DataParseError(CookieCloudError):
"""数据解析错误异常"""
def __init__(self, message: str, raw_data: str = None):
details = {}
if raw_data:
details['raw_data_length'] = len(raw_data)
super().__init__(message, details)
class NetworkError(CookieCloudError):
"""网络错误异常"""
def __init__(self, message: str, original_error: Exception = None):
details = {}
if original_error:
details['original_error'] = str(original_error)
super().__init__(message, details)
+126
View File
@@ -0,0 +1,126 @@
"""
CookieCloud数据模型
"""
from dataclasses import dataclass, field
from typing import Optional, Dict, List
from datetime import datetime
@dataclass
class CookieConfig:
"""CookieCloud配置"""
server: str
username: str
password: str
timeout: int = 30
verify_ssl: bool = True
ignore_cookies: List[str] = field(default_factory=lambda: [
"CookieAutoDeleteBrowsingDataCleanup",
"CookieAutoDeleteCleaningDiscarded"
])
def __post_init__(self):
"""验证配置参数"""
if not self.server:
raise ValueError("服务器地址不能为空")
if not self.username:
raise ValueError("用户名不能为空")
if not self.password:
raise ValueError("密码不能为空")
if not self.server.startswith(('http://', 'https://')):
self.server = f"https://{self.server}"
@dataclass
class CookieData:
"""Cookie数据"""
domain: str
name: str
value: str
path: str = "/"
secure: bool = False
http_only: bool = False
expiry: Optional[datetime] = None
def to_dict(self) -> Dict:
"""转换为字典"""
return {
'domain': self.domain,
'name': self.name,
'value': self.value,
'path': self.path,
'secure': self.secure,
'httpOnly': self.http_only,
'expiry': self.expiry.isoformat() if self.expiry else None
}
@classmethod
def from_dict(cls, data: Dict) -> 'CookieData':
"""从字典创建"""
expiry = None
if data.get('expiry'):
try:
expiry = datetime.fromisoformat(data['expiry'])
except (ValueError, TypeError):
pass
return cls(
domain=data.get('domain', ''),
name=data.get('name', ''),
value=data.get('value', ''),
path=data.get('path', '/'),
secure=data.get('secure', False),
http_only=data.get('httpOnly', False),
expiry=expiry
)
@dataclass
class CookieCollection:
"""Cookie集合"""
domain: str
cookies: List[CookieData] = field(default_factory=list)
def to_cookie_string(self, ignore_list: List[str] = None) -> str:
"""转换为cookie字符串"""
ignore_list = ignore_list or []
cookie_parts = []
for cookie in self.cookies:
if cookie.name not in ignore_list:
cookie_parts.append(f"{cookie.name}={cookie.value}")
return ";".join(cookie_parts)
def add_cookie(self, cookie: CookieData):
"""添加cookie"""
self.cookies.append(cookie)
def get_cookie_by_name(self, name: str) -> Optional[CookieData]:
"""根据名称获取cookie"""
for cookie in self.cookies:
if cookie.name == name:
return cookie
return None
@dataclass
class DownloadResult:
"""下载结果"""
success: bool
cookies: Dict[str, CookieCollection] = field(default_factory=dict)
error_message: str = ""
total_domains: int = 0
total_cookies: int = 0
download_time: float = 0.0
def get_cookie_string(self, domain: str) -> Optional[str]:
"""获取指定域名的cookie字符串"""
collection = self.cookies.get(domain)
if collection:
return collection.to_cookie_string()
return None
def get_domains(self) -> List[str]:
"""获取所有域名列表"""
return list(self.cookies.keys())
+14
View File
@@ -0,0 +1,14 @@
# CookieCloud客户端依赖项
# 此模块完全独立,仅使用Python标准库
# Python版本要求
Python>=3.7
# 无外部依赖
# 仅使用Python标准库模块:
# - json
# - urllib
# - dataclasses
# - typing
# - datetime
# - unittest (用于测试)
+54
View File
@@ -0,0 +1,54 @@
"""
CookieCloud客户端安装脚本
"""
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="cookiecloud-client",
version="1.0.0",
author="CookieManager Team",
author_email="support@example.com",
description="一个独立的、可复用的CookieCloud服务器客户端",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/example/cookiecloud-client",
packages=find_packages(),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Topic :: Software Development :: Libraries :: Python Modules",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
],
python_requires=">=3.7",
install_requires=[
# 无外部依赖,仅使用Python标准库
],
extras_require={
"dev": [
"pytest>=6.0",
"pytest-cov>=2.0",
"black>=21.0",
"flake8>=3.9",
],
},
entry_points={
"console_scripts": [
"cookiecloud-client=cookiecloud_client.cli:main",
],
},
project_urls={
"Bug Reports": "https://github.com/example/cookiecloud-client/issues",
"Source": "https://github.com/example/cookiecloud-client",
"Documentation": "https://github.com/example/cookiecloud-client#readme",
},
)
+295
View File
@@ -0,0 +1,295 @@
"""
CookieCloud客户端单元测试
"""
import unittest
from unittest.mock import Mock, patch, MagicMock
import json
from cookiecloud_client import (
CookieCloudClient,
CookieConfig,
CookieCloudError,
ConfigurationError,
ConnectionError,
AuthenticationError,
DataParseError,
NetworkError
)
class TestCookieConfig(unittest.TestCase):
"""测试CookieConfig配置类"""
def test_valid_config(self):
"""测试有效配置"""
config = CookieConfig(
server="https://example.com",
username="user",
password="pass"
)
self.assertEqual(config.server, "https://example.com")
self.assertEqual(config.username, "user")
self.assertEqual(config.password, "pass")
self.assertEqual(config.timeout, 30)
self.assertTrue(config.verify_ssl)
def test_config_with_custom_params(self):
"""测试自定义参数配置"""
config = CookieConfig(
server="https://example.com",
username="user",
password="pass",
timeout=60,
verify_ssl=False,
ignore_cookies=["test_cookie"]
)
self.assertEqual(config.timeout, 60)
self.assertFalse(config.verify_ssl)
self.assertEqual(config.ignore_cookies, ["test_cookie"])
def test_config_auto_add_protocol(self):
"""测试自动添加协议"""
config = CookieConfig(
server="example.com",
username="user",
password="pass"
)
self.assertTrue(config.server.startswith("https://"))
def test_config_empty_server(self):
"""测试空服务器地址"""
with self.assertRaises(ValueError):
CookieConfig(server="", username="user", password="pass")
def test_config_empty_username(self):
"""测试空用户名"""
with self.assertRaises(ValueError):
CookieConfig(server="https://example.com", username="", password="pass")
def test_config_empty_password(self):
"""测试空密码"""
with self.assertRaises(ValueError):
CookieConfig(server="https://example.com", username="user", password="")
class TestCookieCloudClient(unittest.TestCase):
"""测试CookieCloudClient客户端类"""
def setUp(self):
"""测试前准备"""
self.config = CookieConfig(
server="https://test.example.com",
username="testuser",
password="testpass"
)
self.client = CookieCloudClient(self.config)
def test_client_initialization(self):
"""测试客户端初始化"""
self.assertIsInstance(self.client.config, CookieConfig)
self.assertIsNone(self.client.last_download_time)
self.assertEqual(self.client.download_count, 0)
def test_client_invalid_config(self):
"""测试无效配置"""
with self.assertRaises(ConfigurationError):
CookieCloudClient("invalid_config")
@patch('urllib.request.urlopen')
def test_download_success(self, mock_urlopen):
"""测试成功下载"""
mock_response = Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({
"cookie_data": {
"test.com": [
{
"domain": "test.com",
"name": "session",
"value": "test_value",
"path": "/",
"secure": False,
"httpOnly": False
}
]
}
}).encode('utf-8')
mock_urlopen.return_value = mock_response
result = self.client.download()
self.assertTrue(result.success)
self.assertEqual(result.total_domains, 1)
self.assertEqual(result.total_cookies, 1)
self.assertIsNotNone(self.client.last_download_time)
self.assertEqual(self.client.download_count, 1)
@patch('urllib.request.urlopen')
def test_download_authentication_error(self, mock_urlopen):
"""测试认证失败"""
import urllib.error
mock_urlopen.side_effect = urllib.error.HTTPError(
url="https://test.example.com/get/testuser",
code=401,
msg="Unauthorized",
hdrs={},
fp=None
)
with self.assertRaises(AuthenticationError):
self.client.download()
@patch('urllib.request.urlopen')
def test_download_connection_error(self, mock_urlopen):
"""测试连接错误"""
import urllib.error
mock_urlopen.side_effect = urllib.error.HTTPError(
url="https://test.example.com/get/testuser",
code=404,
msg="Not Found",
hdrs={},
fp=None
)
with self.assertRaises(ConnectionError):
self.client.download()
@patch('urllib.request.urlopen')
def test_download_network_error(self, mock_urlopen):
"""测试网络错误"""
import urllib.error
mock_urlopen.side_effect = urllib.error.URLError("Connection refused")
with self.assertRaises(NetworkError):
self.client.download()
@patch('urllib.request.urlopen')
def test_download_empty_data(self, mock_urlopen):
"""测试空数据"""
mock_response = Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({}).encode('utf-8')
mock_urlopen.return_value = mock_response
with self.assertRaises(DataParseError):
self.client.download()
@patch('urllib.request.urlopen')
def test_test_connection_success(self, mock_urlopen):
"""测试连接测试成功"""
mock_response = Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({
"cookie_data": {}
}).encode('utf-8')
mock_urlopen.return_value = mock_response
success, message = self.client.test_connection()
self.assertTrue(success)
self.assertEqual(message, "连接成功")
@patch('urllib.request.urlopen')
def test_test_connection_failure(self, mock_urlopen):
"""测试连接测试失败"""
import urllib.error
mock_urlopen.side_effect = urllib.error.HTTPError(
url="https://test.example.com/get/testuser",
code=401,
msg="Unauthorized",
hdrs={},
fp=None
)
success, message = self.client.test_connection()
self.assertFalse(success)
self.assertIn("认证失败", message)
@patch('urllib.request.urlopen')
def test_download_for_domain(self, mock_urlopen):
"""测试下载指定域名"""
mock_response = Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({
"cookie_data": {
"test.com": [
{
"domain": "test.com",
"name": "session",
"value": "test_value",
"path": "/",
"secure": False,
"httpOnly": False
}
]
}
}).encode('utf-8')
mock_urlopen.return_value = mock_response
cookie_str = self.client.download_for_domain("test.com")
self.assertIsNotNone(cookie_str)
self.assertIn("session=test_value", cookie_str)
@patch('urllib.request.urlopen')
def test_download_for_domains(self, mock_urlopen):
"""测试批量下载多个域名"""
mock_response = Mock()
mock_response.status = 200
mock_response.read.return_value = json.dumps({
"cookie_data": {
"test1.com": [
{"domain": "test1.com", "name": "cookie1", "value": "value1", "path": "/"}
],
"test2.com": [
{"domain": "test2.com", "name": "cookie2", "value": "value2", "path": "/"}
]
}
}).encode('utf-8')
mock_urlopen.return_value = mock_response
domains = ["test1.com", "test2.com", "test3.com"]
cookies = self.client.download_for_domains(domains)
self.assertEqual(len(cookies), 3)
self.assertIn("cookie1=value1", cookies["test1.com"])
self.assertIn("cookie2=value2", cookies["test2.com"])
self.assertIsNone(cookies["test3.com"])
class TestExceptions(unittest.TestCase):
"""测试异常类"""
def test_cookie_cloud_error(self):
"""测试基础异常"""
error = CookieCloudError("测试错误", {"key": "value"})
self.assertEqual(error.message, "测试错误")
self.assertEqual(error.details, {"key": "value"})
self.assertIn("测试错误", str(error))
def test_configuration_error(self):
"""测试配置错误"""
error = ConfigurationError("配置错误", config_key="server")
self.assertEqual(error.message, "配置错误")
self.assertEqual(error.details["config_key"], "server")
def test_connection_error(self):
"""测试连接错误"""
error = ConnectionError("连接失败", server="example.com", status_code=404)
self.assertEqual(error.message, "连接失败")
self.assertEqual(error.details["server"], "example.com")
self.assertEqual(error.details["status_code"], 404)
def test_authentication_error(self):
"""测试认证错误"""
error = AuthenticationError("认证失败", username="testuser")
self.assertEqual(error.message, "认证失败")
self.assertEqual(error.details["username"], "testuser")
if __name__ == '__main__':
unittest.main()
+8
View File
@@ -0,0 +1,8 @@
"""
版本信息
"""
__version__ = '1.0.0'
__author__ = 'CookieManager Team'
__email__ = 'support@example.com'
__license__ = 'MIT'
+647
View File
@@ -343,3 +343,650 @@
2026-03-02 16:38:22,061 - INFO - 用户 用户A 处理完成
2026-03-02 16:38:22,075 - INFO - ===== Cookie 监控结束 =====
2026-03-02 16:38:22,102 - INFO - 成功处理: 1 个用户,失败: 0 个用户
2026-03-02 18:56:27,278 - INFO - ===== Cookie 监控开始 =====
2026-03-02 18:56:27,279 - INFO - 开始处理用户: 用户A
2026-03-02 18:56:27,279 - INFO - 处理网站: 用户A - 网站A
2026-03-02 18:56:27,280 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 18:56:27,280 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 18:56:54,215 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 18:56:54,216 - INFO - 登录失败: 网站A
2026-03-02 18:56:54,435 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-02 18:56:54,508 - INFO - 已达到最大失败次数,已发送通知并重置计数: 网站A
2026-03-02 18:56:55,613 - INFO - 用户 用户A 处理完成
2026-03-02 18:56:55,615 - INFO - ===== Cookie 监控结束 =====
2026-03-02 18:56:55,616 - INFO - 成功处理: 1 个用户,失败: 0 个用户
2026-03-02 18:57:16,772 - INFO - ===== Cookie 监控开始 =====
2026-03-02 18:57:16,772 - INFO - 开始处理用户: 用户A
2026-03-02 18:57:16,773 - INFO - 处理网站: 用户A - 网站A
2026-03-02 18:57:16,773 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 18:57:16,774 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 18:57:38,432 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 18:57:38,433 - INFO - 登录失败: 网站A
2026-03-02 18:57:38,434 - INFO - 当前失败次数: 1/3
2026-03-02 18:57:39,475 - INFO - 用户 用户A 处理完成
2026-03-02 18:57:39,479 - INFO - ===== Cookie 监控结束 =====
2026-03-02 18:57:39,480 - INFO - 成功处理: 1 个用户,失败: 0 个用户
2026-03-02 19:06:12,869 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:06:12,870 - INFO - 开始处理用户: 用户A
2026-03-02 19:06:12,871 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:06:12,871 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:06:12,872 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:06:13,899 - INFO - 获取到 4 个 cookie:
2026-03-02 19:06:13,900 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:06:13,902 - INFO - - edentoken: 13548569666
2026-03-02 19:06:13,903 - INFO - - user: 13548569666
2026-03-02 19:06:13,904 - INFO - - userType: 2
2026-03-02 19:08:41,909 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:08:41,910 - INFO - 登录失败: 网站A
2026-03-02 19:08:41,913 - INFO - 当前失败次数: 2/3
2026-03-02 19:08:43,011 - INFO - 用户 用户A 处理完成
2026-03-02 19:08:43,019 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:08:43,020 - INFO - 成功处理: 1 个用户,失败: 0 个用户
2026-03-02 19:09:07,392 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:09:07,393 - INFO - 开始处理用户: 用户A
2026-03-02 19:09:07,393 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:09:07,393 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:09:07,394 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:09:08,548 - INFO - 获取到 4 个 cookie:
2026-03-02 19:09:08,549 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:09:08,549 - INFO - - edentoken: 13548569666
2026-03-02 19:09:08,549 - INFO - - user: 13548569666
2026-03-02 19:09:08,550 - INFO - - userType: 2
2026-03-02 19:09:24,826 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:09:24,827 - INFO - 登录失败: 网站A
2026-03-02 19:09:24,974 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-02 19:09:24,975 - INFO - 已达到最大失败次数,已发送通知并重置计数: 网站A
2026-03-02 19:09:26,021 - INFO - 用户 用户A 处理完成
2026-03-02 19:09:26,022 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:09:26,023 - INFO - 成功处理: 1 个用户,失败: 0 个用户
2026-03-02 19:18:24,406 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:18:24,408 - INFO - 开始处理用户: 用户A
2026-03-02 19:18:24,408 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:18:24,409 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:18:24,409 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:18:25,149 - INFO - 获取到 4 个 cookie:
2026-03-02 19:18:25,149 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:18:25,150 - INFO - - edentoken: 13548569666
2026-03-02 19:18:25,150 - INFO - - user: 13548569666
2026-03-02 19:18:25,151 - INFO - - userType: 2
2026-03-02 19:19:20,811 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:19:20,812 - INFO - 登录失败: 网站A
2026-03-02 19:19:20,826 - INFO - 当前失败次数: 1/3
2026-03-02 19:19:21,868 - INFO - 用户 用户A 处理完成
2026-03-02 19:19:21,875 - INFO - 开始处理用户: 用户B
2026-03-02 19:19:21,876 - INFO - 处理网站: 用户B - 网站A
2026-03-02 19:19:21,879 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:19:21,883 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:19:22,305 - INFO - 获取到 6 个 cookie:
2026-03-02 19:19:22,306 - INFO - - _qimei_uuid42: 1a302130f16100ca18af370a47cb8afce807c4a076
2026-03-02 19:19:22,306 - INFO - - _qimei_fingerprint: 50aa79f919511142818459f44ac38dee
2026-03-02 19:19:22,307 - INFO - - _qimei_i_3: 64c844d0c35e05dc9796fc355d8470e5a3eba5f0410e00d3e7...
2026-03-02 19:19:22,307 - INFO - - _qimei_h38: f8e0750618af370a47cb8afc0200000c91a302
2026-03-02 19:19:22,308 - INFO - - merchantType: web
2026-03-02 19:19:22,308 - INFO - - _qimei_i_1: 63f25ad49d0f50dcc497f83153d525e3f0eef5f51508518ae5...
2026-03-02 19:19:42,892 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:19:42,893 - INFO - 登录失败: 网站A
2026-03-02 19:19:42,897 - INFO - 当前失败次数: 1/3
2026-03-02 19:19:43,952 - INFO - 用户 用户B 处理完成
2026-03-02 19:19:43,953 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:19:43,956 - INFO - 成功处理: 2 个用户,失败: 0 个用户
2026-03-02 19:28:58,190 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:28:58,195 - INFO - 开始处理用户: 用户A
2026-03-02 19:28:58,196 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:28:58,197 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:28:58,198 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:28:58,934 - INFO - 获取到 4 个 cookie:
2026-03-02 19:28:58,934 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:28:58,935 - INFO - - edentoken: 13548569666
2026-03-02 19:28:58,936 - INFO - - user: 13548569666
2026-03-02 19:28:58,936 - INFO - - userType: 2
2026-03-02 19:29:09,680 - INFO - 开始设置 4 个 cookie
2026-03-02 19:29:10,559 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:29:10,589 - INFO - 设置 cookie: edentoken
2026-03-02 19:29:10,616 - INFO - 设置 cookie: user
2026-03-02 19:29:10,649 - INFO - 设置 cookie: userType
2026-03-02 19:31:57,850 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:31:57,874 - INFO - 登录失败: 网站A
2026-03-02 19:31:57,908 - INFO - 当前失败次数: 2/3
2026-03-02 19:31:59,017 - INFO - 用户 用户A 处理完成
2026-03-02 19:31:59,026 - INFO - 开始处理用户: 用户B
2026-03-02 19:31:59,034 - INFO - 处理网站: 用户B - 网站A
2026-03-02 19:31:59,049 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:31:59,057 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:31:59,548 - INFO - 获取到 6 个 cookie:
2026-03-02 19:31:59,549 - INFO - - _qimei_uuid42: 1a302130f16100ca18af370a47cb8afce807c4a076
2026-03-02 19:31:59,549 - INFO - - _qimei_fingerprint: 50aa79f919511142818459f44ac38dee
2026-03-02 19:31:59,550 - INFO - - _qimei_i_3: 64c844d0c35e05dc9796fc355d8470e5a3eba5f0410e00d3e7...
2026-03-02 19:31:59,551 - INFO - - _qimei_h38: f8e0750618af370a47cb8afc0200000c91a302
2026-03-02 19:31:59,555 - INFO - - merchantType: web
2026-03-02 19:31:59,557 - INFO - - _qimei_i_1: 63f25ad49d0f50dcc497f83153d525e3f0eef5f51508518ae5...
2026-03-02 19:32:04,579 - INFO - 开始设置 6 个 cookie
2026-03-02 19:32:05,108 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:32:05,123 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:32:05,134 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:32:05,152 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:32:05,176 - INFO - 设置 cookie: merchantType
2026-03-02 19:32:05,191 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:32:20,855 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:32:20,856 - INFO - 登录失败: 网站A
2026-03-02 19:32:20,861 - INFO - 当前失败次数: 2/3
2026-03-02 19:32:21,948 - INFO - 用户 用户B 处理完成
2026-03-02 19:32:21,953 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:32:21,970 - INFO - 成功处理: 2 个用户,失败: 0 个用户
2026-03-02 19:41:26,080 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:41:26,081 - INFO - 开始处理用户: 用户A
2026-03-02 19:41:26,082 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:41:26,082 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:41:26,082 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:41:27,131 - INFO - 获取到 4 个 cookie:
2026-03-02 19:41:27,132 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:41:27,134 - INFO - - edentoken: 13548569666
2026-03-02 19:41:27,135 - INFO - - user: 13548569666
2026-03-02 19:41:27,137 - INFO - - userType: 2
2026-03-02 19:41:32,196 - INFO - 开始设置 4 个 cookie
2026-03-02 19:41:32,218 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:41:32,256 - INFO - 设置 cookie: edentoken
2026-03-02 19:41:32,291 - INFO - 设置 cookie: user
2026-03-02 19:41:32,315 - INFO - 设置 cookie: userType
2026-03-02 19:41:47,436 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:41:47,436 - INFO - 登录失败: 网站A
2026-03-02 19:41:47,804 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-02 19:41:47,828 - INFO - 已达到最大失败次数,已发送通知并重置计数: 网站A
2026-03-02 19:41:48,879 - INFO - 用户 用户A 处理完成
2026-03-02 19:41:48,880 - INFO - 开始处理用户: 用户B
2026-03-02 19:41:48,881 - INFO - 处理网站: 用户B - 网站A
2026-03-02 19:41:48,882 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:41:48,882 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:41:49,422 - INFO - 获取到 17 个 cookie:
2026-03-02 19:41:49,426 - INFO - - _qimei_uuid42: 1a302130f16100ca18af370a47cb8afce807c4a076
2026-03-02 19:41:49,435 - INFO - - _qimei_fingerprint: 50aa79f919511142818459f44ac38dee
2026-03-02 19:41:49,481 - INFO - - _qimei_i_3: 64c844d0c35e05dc9796fc355d8470e5a3eba5f0410e00d3e7...
2026-03-02 19:41:49,561 - INFO - - _qimei_h38: f8e0750618af370a47cb8afc0200000c91a302
2026-03-02 19:41:49,583 - INFO - - merchantType: web
2026-03-02 19:41:49,596 - INFO - - _qimei_i_1: 63f25ad49d0f50dcc497f83153d525e3f0eef5f51508518ae5...
2026-03-02 19:41:49,609 - INFO - - JSESSIONID: B93CC37376EFC653A59B550FE761CC72
2026-03-02 19:41:49,612 - INFO - - _qimei_i_1: 0
2026-03-02 19:41:49,662 - INFO - - merchantType: 0
2026-03-02 19:41:49,665 - INFO - - _qimei_h38: 0
2026-03-02 19:41:49,666 - INFO - - _qimei_i_3: 0
2026-03-02 19:41:49,668 - INFO - - _qimei_fingerprint: 0
2026-03-02 19:41:49,672 - INFO - - _qimei_uuid42: 0
2026-03-02 19:41:49,672 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:41:49,674 - INFO - - edentoken: 13548569666
2026-03-02 19:41:49,675 - INFO - - user: 13548569666
2026-03-02 19:41:49,676 - INFO - - userType: 2
2026-03-02 19:41:53,678 - INFO - 开始设置 17 个 cookie
2026-03-02 19:41:54,168 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:41:54,177 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:41:54,191 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:41:54,205 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:41:54,218 - INFO - 设置 cookie: merchantType
2026-03-02 19:41:54,228 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:41:54,240 - INFO - 设置 cookie: JSESSIONID
2026-03-02 19:41:54,250 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:41:54,263 - INFO - 设置 cookie: merchantType
2026-03-02 19:41:54,277 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:41:54,290 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:41:54,302 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:41:54,315 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:41:54,328 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:41:54,339 - INFO - 设置 cookie: edentoken
2026-03-02 19:41:54,350 - INFO - 设置 cookie: user
2026-03-02 19:41:54,362 - INFO - 设置 cookie: userType
2026-03-02 19:44:10,871 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:44:10,872 - INFO - 登录失败: 网站A
2026-03-02 19:44:11,050 - INFO - 已发送失败通知: 用户B - 网站A
2026-03-02 19:44:11,111 - INFO - 已达到最大失败次数,已发送通知并重置计数: 网站A
2026-03-02 19:44:12,178 - INFO - 用户 用户B 处理完成
2026-03-02 19:44:12,181 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:44:12,187 - INFO - 成功处理: 2 个用户,失败: 0 个用户
2026-03-02 19:44:29,316 - INFO - ===== Cookie 监控开始 =====
2026-03-02 19:44:29,316 - INFO - 开始处理用户: 用户A
2026-03-02 19:44:29,317 - INFO - 处理网站: 用户A - 网站A
2026-03-02 19:44:29,317 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:44:29,318 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:44:31,320 - INFO - 获取到 4 个 cookie:
2026-03-02 19:44:31,321 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:44:31,324 - INFO - - edentoken: 13548569666
2026-03-02 19:44:31,325 - INFO - - user: 13548569666
2026-03-02 19:44:31,326 - INFO - - userType: 2
2026-03-02 19:44:34,631 - INFO - 开始设置 4 个 cookie
2026-03-02 19:44:34,649 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:44:34,666 - INFO - 设置 cookie: edentoken
2026-03-02 19:44:34,684 - INFO - 设置 cookie: user
2026-03-02 19:44:34,709 - INFO - 设置 cookie: userType
2026-03-02 19:44:49,463 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:44:49,465 - INFO - 登录失败: 网站A
2026-03-02 19:44:49,466 - INFO - 当前失败次数: 1/3
2026-03-02 19:44:50,505 - INFO - 用户 用户A 处理完成
2026-03-02 19:44:50,506 - INFO - 开始处理用户: 用户B
2026-03-02 19:44:50,506 - INFO - 处理网站: 用户B - 网站A
2026-03-02 19:44:50,507 - INFO - 尝试使用本地 cookie 登录: 网站A
2026-03-02 19:44:50,508 - INFO - 从 Cookie Cloud 获取 cookie: 网站A
2026-03-02 19:44:50,863 - INFO - 获取到 17 个 cookie:
2026-03-02 19:44:50,864 - INFO - - _qimei_uuid42: 1a302130f16100ca18af370a47cb8afce807c4a076
2026-03-02 19:44:50,865 - INFO - - _qimei_fingerprint: 50aa79f919511142818459f44ac38dee
2026-03-02 19:44:50,865 - INFO - - _qimei_i_3: 64c844d0c35e05dc9796fc355d8470e5a3eba5f0410e00d3e7...
2026-03-02 19:44:50,866 - INFO - - _qimei_h38: f8e0750618af370a47cb8afc0200000c91a302
2026-03-02 19:44:50,866 - INFO - - merchantType: web
2026-03-02 19:44:50,867 - INFO - - _qimei_i_1: 63f25ad49d0f50dcc497f83153d525e3f0eef5f51508518ae5...
2026-03-02 19:44:50,868 - INFO - - JSESSIONID: B93CC37376EFC653A59B550FE761CC72
2026-03-02 19:44:50,868 - INFO - - _qimei_i_1: 0
2026-03-02 19:44:50,868 - INFO - - merchantType: 0
2026-03-02 19:44:50,869 - INFO - - _qimei_h38: 0
2026-03-02 19:44:50,870 - INFO - - _qimei_i_3: 0
2026-03-02 19:44:50,870 - INFO - - _qimei_fingerprint: 0
2026-03-02 19:44:50,871 - INFO - - _qimei_uuid42: 0
2026-03-02 19:44:50,872 - INFO - - LMKBIUSS: eyJhY2NvdW50SWQiOjIzMzk0OTQ3NTAwMjA0OSwicGhvbmUiOi...
2026-03-02 19:44:50,872 - INFO - - edentoken: 13548569666
2026-03-02 19:44:50,873 - INFO - - user: 13548569666
2026-03-02 19:44:50,873 - INFO - - userType: 2
2026-03-02 19:44:54,212 - INFO - 开始设置 17 个 cookie
2026-03-02 19:44:54,239 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:44:54,258 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:44:54,286 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:44:54,306 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:44:54,323 - INFO - 设置 cookie: merchantType
2026-03-02 19:44:54,344 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:44:54,366 - INFO - 设置 cookie: JSESSIONID
2026-03-02 19:44:54,391 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:44:54,414 - INFO - 设置 cookie: merchantType
2026-03-02 19:44:54,436 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:44:54,456 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:44:54,474 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:44:54,503 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:44:54,529 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:44:54,554 - INFO - 设置 cookie: edentoken
2026-03-02 19:44:54,571 - INFO - 设置 cookie: user
2026-03-02 19:44:54,590 - INFO - 设置 cookie: userType
2026-03-02 19:45:10,024 - INFO - Cookie Cloud 登录失败: 网站A
2026-03-02 19:45:10,025 - INFO - 登录失败: 网站A
2026-03-02 19:45:10,026 - INFO - 当前失败次数: 1/3
2026-03-02 19:45:11,099 - INFO - 用户 用户B 处理完成
2026-03-02 19:45:11,100 - INFO - ===== Cookie 监控结束 =====
2026-03-02 19:45:11,100 - INFO - 成功处理: 2 个用户,失败: 0 个用户
2026-03-02 19:47:06,309 - INFO - ==================================================
2026-03-02 19:47:06,310 - INFO - Cookie 监控开始
2026-03-02 19:47:06,310 - INFO - 时间: 2026-03-02 19:47:06
2026-03-02 19:47:06,311 - INFO - ==================================================
2026-03-02 19:47:06,311 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 19:47:06,312 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 19:47:08,398 - INFO - 获取到 278 个域名,共 803 个 cookie
2026-03-02 19:47:08,399 - INFO -
处理网站: 网站A
2026-03-02 19:47:08,399 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 19:47:08,400 - INFO - 找到 4 个 cookie
2026-03-02 19:47:19,291 - INFO - 开始设置 4 个 cookie
2026-03-02 19:47:19,316 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:47:19,336 - INFO - 设置 cookie: edentoken
2026-03-02 19:47:19,351 - INFO - 设置 cookie: user
2026-03-02 19:47:19,367 - INFO - 设置 cookie: userType
2026-03-02 19:49:03,692 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:49:03,700 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 19:49:03,703 - INFO - 总网站数: 1
2026-03-02 19:49:03,704 - INFO - 成功: 0, 失败: 1
2026-03-02 19:49:03,705 - INFO -
失败详情:
2026-03-02 19:49:03,706 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:49:04,751 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 19:49:04,790 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 19:49:05,278 - INFO - 获取到 814 个域名,共 2941 个 cookie
2026-03-02 19:49:05,282 - INFO -
处理网站: 网站A
2026-03-02 19:49:05,299 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 19:49:05,303 - INFO - 找到 17 个 cookie
2026-03-02 19:49:19,363 - INFO - 开始设置 17 个 cookie
2026-03-02 19:49:19,378 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:49:19,392 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:49:19,408 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:49:19,426 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:49:19,443 - INFO - 设置 cookie: merchantType
2026-03-02 19:49:19,459 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:49:19,475 - INFO - 设置 cookie: JSESSIONID
2026-03-02 19:49:19,490 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:49:19,506 - INFO - 设置 cookie: merchantType
2026-03-02 19:49:19,521 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:49:19,534 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:49:19,549 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:49:19,562 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:49:19,578 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:49:19,592 - INFO - 设置 cookie: edentoken
2026-03-02 19:49:19,601 - INFO - 设置 cookie: user
2026-03-02 19:49:19,615 - INFO - 设置 cookie: userType
2026-03-02 19:51:34,896 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:51:34,902 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-02 19:51:34,904 - INFO - 总网站数: 1
2026-03-02 19:51:34,905 - INFO - 成功: 0, 失败: 1
2026-03-02 19:51:34,906 - INFO -
失败详情:
2026-03-02 19:51:34,907 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:51:35,961 - INFO -
==================================================
2026-03-02 19:51:35,976 - INFO - Cookie 监控结束
2026-03-02 19:51:35,988 - INFO - ==================================================
2026-03-02 19:52:33,025 - INFO - ==================================================
2026-03-02 19:52:33,026 - INFO - Cookie 监控开始
2026-03-02 19:52:33,026 - INFO - 时间: 2026-03-02 19:52:33
2026-03-02 19:52:33,027 - INFO - ==================================================
2026-03-02 19:52:33,027 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 19:52:33,028 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 19:52:35,067 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-02 19:52:35,069 - INFO -
处理网站: 网站A
2026-03-02 19:52:35,070 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 19:52:35,071 - INFO - 找到 4 个 cookie
2026-03-02 19:52:37,975 - INFO - 开始设置 4 个 cookie
2026-03-02 19:52:37,997 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:52:38,014 - INFO - 设置 cookie: edentoken
2026-03-02 19:52:38,032 - INFO - 设置 cookie: user
2026-03-02 19:52:38,056 - INFO - 设置 cookie: userType
2026-03-02 19:52:53,369 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:52:53,618 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-02 19:52:53,621 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 19:52:53,623 - INFO - 总网站数: 1
2026-03-02 19:52:53,628 - INFO - 成功: 0, 失败: 1
2026-03-02 19:52:53,630 - INFO -
失败详情:
2026-03-02 19:52:53,632 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:52:54,675 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 19:52:54,676 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 19:52:55,007 - INFO - 获取到 814 个域名,共 2940 个 cookie
2026-03-02 19:52:55,009 - INFO -
处理网站: 网站A
2026-03-02 19:52:55,011 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 19:52:55,012 - INFO - 找到 17 个 cookie
2026-03-02 19:52:58,102 - INFO - 开始设置 17 个 cookie
2026-03-02 19:52:58,116 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:52:58,131 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:52:58,145 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:52:58,161 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:52:58,178 - INFO - 设置 cookie: merchantType
2026-03-02 19:52:58,191 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:52:58,206 - INFO - 设置 cookie: JSESSIONID
2026-03-02 19:52:58,221 - INFO - 设置 cookie: _qimei_i_1
2026-03-02 19:52:58,236 - INFO - 设置 cookie: merchantType
2026-03-02 19:52:58,251 - INFO - 设置 cookie: _qimei_h38
2026-03-02 19:52:58,266 - INFO - 设置 cookie: _qimei_i_3
2026-03-02 19:52:58,283 - INFO - 设置 cookie: _qimei_fingerprint
2026-03-02 19:52:58,299 - INFO - 设置 cookie: _qimei_uuid42
2026-03-02 19:52:58,316 - INFO - 设置 cookie: LMKBIUSS
2026-03-02 19:52:58,332 - INFO - 设置 cookie: edentoken
2026-03-02 19:52:58,348 - INFO - 设置 cookie: user
2026-03-02 19:52:58,368 - INFO - 设置 cookie: userType
2026-03-02 19:53:12,951 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:53:13,096 - INFO - 已发送失败通知: 用户B - 网站A
2026-03-02 19:53:13,102 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-02 19:53:13,104 - INFO - 总网站数: 1
2026-03-02 19:53:13,107 - INFO - 成功: 0, 失败: 1
2026-03-02 19:53:13,109 - INFO -
失败详情:
2026-03-02 19:53:13,110 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 19:53:14,193 - INFO -
==================================================
2026-03-02 19:53:14,194 - INFO - Cookie 监控结束
2026-03-02 19:53:14,194 - INFO - ==================================================
2026-03-02 19:57:38,356 - INFO - ==================================================
2026-03-02 19:57:38,357 - INFO - Cookie 监控开始
2026-03-02 19:57:38,357 - INFO - 时间: 2026-03-02 19:57:38
2026-03-02 19:57:38,358 - INFO - ==================================================
2026-03-02 19:57:38,358 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 19:57:38,359 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 19:57:39,474 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-02 19:57:39,475 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 19:57:50,386 - INFO - 开始导入 801 个 cookie
2026-03-02 19:59:53,803 - INFO - Cookie 导入完成: 成功 801, 失败 0
2026-03-02 19:59:53,805 - INFO - 成功导入 801 个 cookie
2026-03-02 19:59:53,805 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 19:59:53,806 - INFO -
验证网站: 网站A
2026-03-02 19:59:53,806 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 20:00:09,296 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 20:00:09,298 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 20:00:09,299 - INFO - 总网站数: 1
2026-03-02 20:00:09,299 - INFO - 成功: 0, 失败: 1
2026-03-02 20:00:09,300 - INFO -
失败详情:
2026-03-02 20:00:09,301 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 20:00:10,370 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 20:00:10,374 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 20:00:10,940 - INFO - 获取到 814 个域名,共 2947 个 cookie
2026-03-02 20:00:10,948 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 20:00:14,614 - INFO - 开始导入 2947 个 cookie
2026-03-02 20:16:17,328 - INFO - ==================================================
2026-03-02 20:16:17,331 - INFO - Cookie 监控开始
2026-03-02 20:16:17,331 - INFO - 时间: 2026-03-02 20:16:17
2026-03-02 20:16:17,332 - INFO - ==================================================
2026-03-02 20:16:17,332 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 20:16:17,332 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 20:16:19,422 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-02 20:16:19,423 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 20:16:33,797 - INFO - 开始导入 801 个 cookie
2026-03-02 20:30:29,314 - INFO - Cookie 导入完成: 成功 801, 失败 0
2026-03-02 20:30:29,347 - INFO - 成功导入 801 个 cookie
2026-03-02 20:30:29,349 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 20:30:29,351 - INFO -
验证网站: 网站A
2026-03-02 20:30:29,352 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 20:31:15,938 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 20:31:16,156 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 20:31:16,174 - INFO - 总网站数: 1
2026-03-02 20:31:16,188 - INFO - 成功: 0, 失败: 1
2026-03-02 20:31:16,195 - INFO -
失败详情:
2026-03-02 20:31:16,204 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 20:31:17,772 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 20:31:17,832 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 20:31:19,351 - INFO - 获取到 814 个域名,共 2946 个 cookie
2026-03-02 20:31:19,469 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 20:31:40,232 - INFO - 开始导入 2946 个 cookie
2026-03-02 23:12:19,893 - INFO - ==================================================
2026-03-02 23:12:19,894 - INFO - Cookie 监控开始
2026-03-02 23:12:19,894 - INFO - 时间: 2026-03-02 23:12:19
2026-03-02 23:12:19,894 - INFO - ==================================================
2026-03-02 23:12:19,895 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 23:12:19,895 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 23:12:21,973 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-02 23:12:21,973 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 23:12:26,570 - INFO - 开始导入 801 个 cookie
2026-03-02 23:14:33,586 - INFO - Cookie 导入完成: 成功 801, 失败 0
2026-03-02 23:14:33,587 - INFO - 成功导入 801 个 cookie
2026-03-02 23:14:33,587 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 23:14:33,588 - INFO -
验证网站: 网站A
2026-03-02 23:14:33,588 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 23:14:52,444 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:14:52,659 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-02 23:14:52,660 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 23:14:52,661 - INFO - 总网站数: 1
2026-03-02 23:14:52,661 - INFO - 成功: 0, 失败: 1
2026-03-02 23:14:52,662 - INFO -
失败详情:
2026-03-02 23:14:52,662 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:14:53,782 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 23:14:53,782 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 23:14:54,433 - INFO - 获取到 814 个域名,共 2950 个 cookie
2026-03-02 23:14:54,433 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 23:14:58,023 - INFO - 开始导入 2950 个 cookie
2026-03-02 23:22:13,589 - INFO - Cookie 导入完成: 成功 2949, 失败 1
2026-03-02 23:22:13,690 - WARNING - 部分 cookie 导入失败
2026-03-02 23:22:13,701 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 23:22:13,704 - INFO -
验证网站: 网站A
2026-03-02 23:22:13,706 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 23:22:13,709 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-02 23:22:13,710 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:22:13,720 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-02 23:22:13,732 - INFO - 总网站数: 1
2026-03-02 23:22:13,748 - INFO - 成功: 0, 失败: 1
2026-03-02 23:22:13,755 - INFO -
失败详情:
2026-03-02 23:22:13,759 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:22:14,205 - INFO -
==================================================
2026-03-02 23:22:14,206 - INFO - Cookie 监控结束
2026-03-02 23:22:14,206 - INFO - ==================================================
2026-03-02 23:24:45,469 - INFO - ==================================================
2026-03-02 23:24:45,470 - INFO - Cookie 监控开始
2026-03-02 23:24:45,470 - INFO - 时间: 2026-03-02 23:24:45
2026-03-02 23:24:45,471 - INFO - ==================================================
2026-03-02 23:24:45,471 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-02 23:24:45,472 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 23:24:51,705 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-02 23:24:51,705 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 23:25:00,772 - INFO - 开始导入 801 个 cookie
2026-03-02 23:26:59,941 - INFO - Cookie 导入完成: 成功 801, 失败 0
2026-03-02 23:26:59,942 - INFO - 成功导入 801 个 cookie
2026-03-02 23:26:59,942 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 23:26:59,943 - INFO -
验证网站: 网站A
2026-03-02 23:26:59,943 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 23:27:14,779 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:27:14,783 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-02 23:27:14,785 - INFO - 总网站数: 1
2026-03-02 23:27:14,786 - INFO - 成功: 0, 失败: 1
2026-03-02 23:27:14,787 - INFO -
失败详情:
2026-03-02 23:27:14,788 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:27:15,886 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-02 23:27:15,889 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-02 23:27:16,629 - INFO - 获取到 814 个域名,共 2948 个 cookie
2026-03-02 23:27:16,631 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-02 23:27:18,380 - INFO - 开始导入 2948 个 cookie
2026-03-02 23:31:37,244 - INFO - Cookie 导入完成: 成功 2947, 失败 1
2026-03-02 23:31:37,246 - WARNING - 部分 cookie 导入失败
2026-03-02 23:31:37,247 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-02 23:31:37,248 - INFO -
验证网站: 网站A
2026-03-02 23:31:37,248 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-02 23:31:37,254 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-02 23:31:37,256 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:31:37,260 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-02 23:31:37,263 - INFO - 总网站数: 1
2026-03-02 23:31:37,264 - INFO - 成功: 0, 失败: 1
2026-03-02 23:31:37,264 - INFO -
失败详情:
2026-03-02 23:31:37,265 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-02 23:31:38,233 - INFO -
==================================================
2026-03-02 23:31:38,235 - INFO - Cookie 监控结束
2026-03-02 23:31:38,236 - INFO - ==================================================
2026-03-03 08:29:26,844 - INFO - ==================================================
2026-03-03 08:29:26,845 - INFO - Cookie 监控开始
2026-03-03 08:29:26,845 - INFO - 时间: 2026-03-03 08:29:26
2026-03-03 08:29:26,846 - INFO - ==================================================
2026-03-03 08:29:26,846 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-03 08:29:26,846 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-03 08:29:33,515 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-03 08:29:33,515 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-03 08:29:34,818 - INFO - 开始导入 801 个 cookie
2026-03-03 08:34:05,206 - INFO - Cookie 导入完成: 成功 800, 失败 1
2026-03-03 08:34:05,227 - WARNING - 部分 cookie 导入失败
2026-03-03 08:34:05,228 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-03 08:34:05,234 - INFO -
验证网站: 网站A
2026-03-03 08:34:05,236 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-03 08:34:05,239 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-03 08:34:05,240 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:34:05,255 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-03 08:34:05,259 - INFO - 总网站数: 1
2026-03-03 08:34:05,261 - INFO - 成功: 0, 失败: 1
2026-03-03 08:34:05,270 - INFO -
失败详情:
2026-03-03 08:34:05,271 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:34:05,974 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-03 08:34:05,976 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-03 08:34:06,647 - INFO - 获取到 813 个域名,共 2940 个 cookie
2026-03-03 08:34:06,648 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-03 08:34:09,040 - INFO - 开始导入 2940 个 cookie
2026-03-03 08:47:28,987 - INFO - Cookie 导入完成: 成功 2939, 失败 1
2026-03-03 08:47:29,120 - WARNING - 部分 cookie 导入失败
2026-03-03 08:47:29,235 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-03 08:47:29,271 - INFO -
验证网站: 网站A
2026-03-03 08:47:29,313 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-03 08:47:29,334 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-03 08:47:29,359 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:47:30,226 - INFO - 已发送失败通知: 用户B - 网站A
2026-03-03 08:47:30,227 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-03 08:47:30,229 - INFO - 总网站数: 1
2026-03-03 08:47:30,230 - INFO - 成功: 0, 失败: 1
2026-03-03 08:47:30,231 - INFO -
失败详情:
2026-03-03 08:47:30,234 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:47:30,235 - INFO -
==================================================
2026-03-03 08:47:30,236 - INFO - Cookie 监控结束
2026-03-03 08:47:30,237 - INFO - ==================================================
2026-03-03 08:47:50,074 - INFO - ==================================================
2026-03-03 08:47:50,075 - INFO - Cookie 监控开始
2026-03-03 08:47:50,076 - INFO - 时间: 2026-03-03 08:47:50
2026-03-03 08:47:50,076 - INFO - ==================================================
2026-03-03 08:47:50,077 - INFO - ==================== 开始处理用户: 用户A ====================
2026-03-03 08:47:50,077 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-03 08:47:56,370 - INFO - 获取到 278 个域名,共 801 个 cookie
2026-03-03 08:47:56,371 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-03 08:48:03,542 - INFO - 开始导入 801 个 cookie
2026-03-03 08:49:19,995 - INFO - Cookie 导入完成: 成功 800, 失败 1
2026-03-03 08:49:19,995 - WARNING - 部分 cookie 导入失败
2026-03-03 08:49:19,996 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-03 08:49:19,996 - INFO -
验证网站: 网站A
2026-03-03 08:49:19,997 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-03 08:49:20,040 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-03 08:49:20,042 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:49:22,005 - INFO - 已发送失败通知: 用户A - 网站A
2026-03-03 08:49:22,007 - INFO -
==================== 用户 用户A 处理结果汇总 ====================
2026-03-03 08:49:22,007 - INFO - 总网站数: 1
2026-03-03 08:49:22,008 - INFO - 成功: 0, 失败: 1
2026-03-03 08:49:22,008 - INFO -
失败详情:
2026-03-03 08:49:22,009 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:49:22,009 - INFO - ==================== 开始处理用户: 用户B ====================
2026-03-03 08:49:22,009 - INFO - 步骤1: 从 Cookie Cloud 获取所有 cookies
2026-03-03 08:49:22,809 - INFO - 获取到 813 个域名,共 2940 个 cookie
2026-03-03 08:49:22,819 - INFO - 步骤2: 一次性导入所有 cookies 到浏览器
2026-03-03 08:49:30,875 - INFO - 开始导入 2940 个 cookie
2026-03-03 08:49:43,208 - INFO - Cookie 导入完成: 成功 2939, 失败 1
2026-03-03 08:49:43,209 - WARNING - 部分 cookie 导入失败
2026-03-03 08:49:43,209 - INFO - 步骤3: 依次验证各网站登录状态
2026-03-03 08:49:43,209 - INFO -
验证网站: 网站A
2026-03-03 08:49:43,210 - INFO - URL: https://lmkbi.95155.com/bi-system/#/carUnpetrifiedComAll
2026-03-03 08:49:43,212 - ERROR - 验证登录状态失败:
与页面的连接已断开。
版本: 4.1.0.18
2026-03-03 08:49:43,214 - WARNING - ✗ 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:49:43,219 - INFO -
==================== 用户 用户B 处理结果汇总 ====================
2026-03-03 08:49:43,223 - INFO - 总网站数: 1
2026-03-03 08:49:43,227 - INFO - 成功: 0, 失败: 1
2026-03-03 08:49:43,236 - INFO -
失败详情:
2026-03-03 08:49:43,236 - INFO - - 网站A: 登录状态验证失败(cookies可能已过期或选择器配置错误)
2026-03-03 08:49:43,691 - INFO -
==================================================
2026-03-03 08:49:43,692 - INFO - Cookie 监控结束
2026-03-03 08:49:43,692 - INFO - ==================================================
+394
View File
@@ -0,0 +1,394 @@
"""
MoviePilot Cookie功能示例程序
从CookieCloud下载数据并注入浏览器访问网站
"""
import json
import time
import hashlib
import base64
from typing import Dict, List, Optional, Tuple
from dataclasses import dataclass
import urllib.request
import urllib.error
from Crypto.Cipher import AES
@dataclass
class CookieCloudConfig:
"""CookieCloud配置"""
server: str
username: str
password: str
timeout: int = 30
class CookieCloudDownloader:
"""从CookieCloud服务器下载cookie数据"""
def __init__(self, config: CookieCloudConfig):
self.config = config
def _get_crypt_key(self) -> bytes:
combined_string = f"{self.config.username}-{self.config.password}"
return hashlib.md5(combined_string.encode('utf-8')).hexdigest()[:16].encode("utf-8")
def _bytes_to_key(self, data: bytes, salt: bytes, output: int = 48) -> bytes:
assert len(salt) == 8, len(salt)
data += salt
key = hashlib.md5(data).digest()
final_key = key
while len(final_key) < output:
key = hashlib.md5(key + data).digest()
final_key += key
return final_key[:output]
def _decrypt(self, encrypted: str, passphrase: bytes) -> bytes:
encrypted_bytes = base64.b64decode(encrypted)
assert encrypted_bytes.startswith(b"Salted__"), "Invalid encrypted data format"
salt = encrypted_bytes[8:16]
key_iv = self._bytes_to_key(passphrase, salt, 32 + 16)
key = key_iv[:32]
iv = key_iv[32:]
aes = AES.new(key, AES.MODE_CBC, iv)
decrypted_padded = aes.decrypt(encrypted_bytes[16:])
padding_length = decrypted_padded[-1]
if isinstance(padding_length, str):
padding_length = ord(padding_length)
return decrypted_padded[:-padding_length]
def _get_url_domain(self, domain: str) -> str:
if not domain:
return ""
domain = domain.lstrip('.')
if ":" in domain:
domain = domain.split(":")[0]
parts = domain.split(".")
if all(part.isdigit() for part in parts):
return domain
if len(parts) >= 2:
return ".".join(parts[-2:])
return domain
def download_all(self) -> Tuple[Optional[Dict], str]:
"""下载所有cookie和local storage数据"""
try:
url = f"{self.config.server}/get/{self.config.username}"
request = urllib.request.Request(
url,
headers={
'Content-Type': 'application/json',
'User-Agent': 'MoviePilot-Cookie-Client/1.0'
},
method='GET'
)
response = urllib.request.urlopen(request, timeout=self.config.timeout)
if response.status != 200:
return None, f"服务器返回错误状态码: {response.status}"
result = json.loads(response.read().decode('utf-8'))
if not result:
return None, "服务器返回数据为空"
encrypted = result.get("encrypted")
if not encrypted:
return None, "未获取到cookie密文"
crypt_key = self._get_crypt_key()
try:
decrypted_data = self._decrypt(encrypted, crypt_key)
result = json.loads(decrypted_data.decode("utf-8"))
except Exception as e:
return None, f"cookie解密失败: {str(e)}"
if not result:
return None, "cookie解密为空"
cookie_data = result.get("cookie_data", {})
local_storage_data = result.get("local_storage_data", {})
total_cookies = sum(len(v) for v in cookie_data.values())
total_ls = sum(len(v) for v in local_storage_data.values())
print(f" 下载完成: {len(cookie_data)} 个域名的Cookie({total_cookies}个), {len(local_storage_data)} 个域名的Local Storage({total_ls}个)")
return {"cookies": cookie_data, "local_storage": local_storage_data}, ""
except urllib.error.HTTPError as e:
if e.code == 401:
return None, "认证失败,请检查用户名和密码"
else:
return None, f"HTTP错误: {e.code} {e.reason}"
except urllib.error.URLError as e:
return None, f"网络连接失败: {e.reason}"
except Exception as e:
return None, f"下载失败: {str(e)}"
class BrowserController:
"""使用Playwright控制浏览器"""
def __init__(self, headless: bool = False, use_edge: bool = False):
self.headless = headless
self.use_edge = use_edge
self.browser = None
self.context = None
self.page = None
self.playwright = None
def start(self) -> bool:
try:
from playwright.sync_api import sync_playwright
self.playwright = sync_playwright().start()
if self.use_edge:
self.browser = self.playwright.chromium.launch(
channel="msedge",
headless=self.headless,
args=['--disable-blink-features=AutomationControlled', '--disable-dev-shm-usage', '--no-sandbox']
)
else:
self.browser = self.playwright.chromium.launch(
headless=self.headless,
args=['--disable-blink-features=AutomationControlled', '--disable-dev-shm-usage', '--no-sandbox']
)
self.context = self.browser.new_context(
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 = self.context.new_page()
print(f"✓ 浏览器启动成功 ({'Edge' if self.use_edge else 'Chromium'})")
return True
except Exception as e:
print(f"✗ 浏览器启动失败: {str(e)}")
return False
def inject_cookies(self, cookies: Dict):
"""注入cookie到浏览器"""
if not self.context or not cookies:
return
try:
playwright_cookies = []
for domain_key, cookie_list in cookies.items():
for cookie in cookie_list:
cookie_domain = cookie.get("domain", "").lstrip('.')
if not cookie_domain:
cookie_domain = domain_key.lstrip('.')
pw_cookie = {
"name": cookie.get("name", ""),
"value": cookie.get("value", ""),
"domain": cookie_domain,
"path": cookie.get("path", "/"),
}
if cookie.get("secure"):
pw_cookie["secure"] = True
if cookie.get("httpOnly"):
pw_cookie["httpOnly"] = True
if cookie.get("expirationDate"):
pw_cookie["expires"] = int(cookie.get("expirationDate"))
playwright_cookies.append(pw_cookie)
self.context.add_cookies(playwright_cookies)
print(f"✓ Cookie注入成功 ({len(playwright_cookies)} 个)")
except Exception as e:
print(f"✗ Cookie注入失败: {str(e)}")
def navigate(self, url: str, wait_time: int = 5, timeout: int = 60) -> bool:
if not self.page:
return False
try:
print(f"正在访问: {url}")
self.page.goto(url, timeout=timeout * 1000)
try:
self.page.wait_for_load_state("networkidle", timeout=timeout * 1000)
except Exception:
print(" networkidle超时,尝试load状态...")
try:
self.page.wait_for_load_state("load", timeout=30000)
except Exception:
print(" load超时,尝试domcontentloaded状态...")
self.page.wait_for_load_state("domcontentloaded", timeout=10000)
time.sleep(wait_time)
print(f"✓ 页面加载完成")
return True
except Exception as e:
print(f"✗ 页面访问失败: {str(e)}")
return False
def check_login_status(self, login_indicator: str) -> bool:
if not self.page:
return False
try:
html_content = self.page.content()
if login_indicator:
if login_indicator in html_content:
print(f"✓ 检测到登录指示器: {login_indicator}")
return True
else:
print(f"✗ 未检测到登录指示器: {login_indicator}")
return False
return False
except Exception as e:
print(f"✗ 登录状态检查失败: {str(e)}")
return False
def take_screenshot(self, filepath: str):
if not self.page:
return
try:
self.page.screenshot(path=filepath)
print(f"✓ 截图已保存: {filepath}")
except Exception as e:
print(f"✗ 截图失败: {str(e)}")
def close(self):
try:
if self.browser:
self.browser.close()
if self.playwright:
self.playwright.stop()
print("✓ 浏览器已关闭")
except Exception as e:
print(f"✗ 关闭浏览器失败: {str(e)}")
class CookieDemo:
"""Cookie功能示例"""
def __init__(self, cookiecloud_config: CookieCloudConfig):
self.downloader = CookieCloudDownloader(cookiecloud_config)
self.browser = None
def run_sites(self, sites: list, headless: bool = False, use_edge: bool = False):
"""下载一次数据,依次访问多个网站"""
# 下载数据
print("=" * 60)
print("从CookieCloud下载数据")
print("=" * 60)
data, error = self.downloader.download_all()
if error:
print(f"✗ 数据下载失败: {error}")
return
# 启动浏览器
print(f"\n启动浏览器")
print("-" * 60)
self.browser = BrowserController(headless=headless, use_edge=use_edge)
if not self.browser.start():
return
# 注入所有cookie
if data and data.get("cookies"):
print(f"\n注入所有cookie到浏览器")
print("-" * 60)
self.browser.inject_cookies(data["cookies"])
# 依次访问每个网站
for idx, site in enumerate(sites, 1):
print(f"\n\n{'=' * 60}")
print(f"访问网站 {idx}/{len(sites)}: {site['name']}")
print(f"URL: {site['url']}")
print("=" * 60)
if not self.browser.navigate(site['url']):
print(f"✗ 页面访问失败")
continue
# 验证登录状态
from urllib.parse import urlparse
parsed = urlparse(site['url'])
target_domain = parsed.netloc
login_indicator = site.get('login_indicator')
is_logged_in = self.browser.check_login_status(login_indicator)
if is_logged_in:
print("✓ Cookie验证成功:已登录状态")
else:
print("⚠ Cookie验证失败:未检测到登录状态")
# 截图
screenshot_path = f"{target_domain.replace('.', '_').replace(':', '_')}_screenshot.png"
self.browser.take_screenshot(screenshot_path)
if idx < len(sites):
print("\n等待3秒后继续下一个网站...")
time.sleep(3)
# 关闭浏览器
print(f"\n关闭浏览器")
print("-" * 60)
self.browser.close()
print("\n" + "=" * 60)
print("所有网站访问完成")
print("=" * 60)
def main():
# 配置CookieCloud
config = CookieCloudConfig(
server="http://192.168.1.100:3000/cookiecloud",
username="qyZpTrgiP5mVwiRZwfBhjz",
password="iGn1B4FnWftp3oj4Ko3jxA",
timeout=30
)
# 创建示例程序
demo = CookieDemo(config)
# 测试网站列表
test_sites = [
{
"url": "https://lmkbi.95155.com/bi-system/#/login",
"name": "BI系统",
"login_indicator": "彭峰"
},
{
"url": "http://192.168.1.100:3000/#/subscribe/movie",
"name": "MoviePilot订阅",
"login_indicator": "搜索"
},
{
"url": "http://192.168.1.102:8418/bwadmin/QueryCarInfo2",
"name": "QueryCarInfo2",
"login_indicator": "工单管理"
}
]
# 下载一次数据,依次访问所有网站
demo.run_sites(
sites=test_sites,
headless=False,
use_edge=True
)
if __name__ == "__main__":
main()
+2 -1
View File
@@ -1,3 +1,4 @@
{
"用户A_网站A": 2
"用户A_网站A": 0,
"用户B_网站A": 1
}