feat: stabilize multi-region runtime sync and worker orchestration

This commit is contained in:
root
2026-04-27 15:48:12 +08:00
parent 7cbde2aa78
commit 215a364891
137 changed files with 31931 additions and 1943 deletions

View File

@@ -13,7 +13,6 @@ import base64 # Base64编码解码
import hashlib # 哈希加密
import json # JSON数据处理
import os # 操作系统接口
import pickle # 序列化反序列化
import random # 随机数生成
import shutil
import subprocess # 子进程管理
@@ -24,6 +23,7 @@ import requests # HTTP请求库
from loguru import logger # 日志记录
from requests.cookies import RequestsCookieJar # Cookie管理
from detect.locked_pickle import load_pickle_locked, save_pickle_atomic
# # 移除自定义子进程类的替换,避免影响其他模块
@@ -109,12 +109,19 @@ class JC(object): # 聚查网API封装类
def __init__(self, proxies: dict = None): # 初始化JC类
self.session = requests.Session() # 创建会话对象
self.session.timeout = 10 # 设置超时时间
self.session.proxies = proxies # 设置代理
self.request_timeout = max(
0.5,
float(os.getenv("DOMAINCHECK_JUCHA_TIMEOUT", "10") or 10),
)
self.base_url = "https://www.jucha.com" # 设置基础URL
self.cookie = requests.cookies.RequestsCookieJar() # 初始化CookieJar
self.juming_cookie = requests.cookies.RequestsCookieJar() # 初始化聚名网CookieJar
def _request(self, method: str, url: str, **kwargs):
kwargs.setdefault("timeout", self.request_timeout)
return getattr(self.session, method)(url, **kwargs)
def _get_headers(self, referer: str = None) -> dict: # 获取请求头可自定义referer
headers = self.headers.copy() # 复制默认请求头
if referer: # 如果指定了referer
@@ -139,7 +146,7 @@ class JC(object): # 聚查网API封装类
return False, f'滑块验证码失败,{retry_times}次内未成功' # 返回失败
def _check_request(self, url: str, data: dict, headers: dict, cookies=None) -> dict: # 检查请求并处理验证码
res = self.session.post(url=url, data=data, headers=headers, cookies=cookies) # 发送POST请求
res = self._request("post", url=url, data=data, headers=headers, cookies=cookies) # 发送POST请求
try:
response = res.json() # 尝试解析JSON
except Exception as e: # JSON解析失败
@@ -179,7 +186,7 @@ class JC(object): # 聚查网API封装类
"seed": calculate_seed(286) # 种子值
}
url = f"{self.base_url}/captcha/init" # 初始化URL
response = self.session.post(url, headers=self.headers, data=data, cookies=self.cookie).json() # 发送请求
response = self._request("post", url, headers=self.headers, data=data, cookies=self.cookie).json() # 发送请求
if response['code'] == 1: # 初始化成功
self.captchaId = response['data']['captchaId'] # 保存验证码ID
self.encryptionPublicKey = response['data']['encryptionPublicKey'] # 保存加密公钥
@@ -234,8 +241,13 @@ class JC(object): # 聚查网API封装类
url = f"{self.base_url}/captcha/verify" # 验证URL
verify_headers = self.headers.copy() # 复制请求头
verify_headers['Content-Type'] = 'application/json' # 设置内容类型(仅用于验证请求)
verify_response = self.session.post(url, headers=verify_headers, data=verify_data,
cookies=self.cookie) # 发送验证请求
verify_response = self._request(
"post",
url,
headers=verify_headers,
data=verify_data,
cookies=self.cookie,
) # 发送验证请求
if verify_response.cookies: # 如果响应中有新的Cookie
self.cookie.update(verify_response.cookies) # 合并Cookie而不是替换
response = verify_response.json() # 解析JSON响应
@@ -254,20 +266,12 @@ class JC(object): # 聚查网API封装类
return False, "Node.js脚本未输出任何内容" # 返回失败
def save_cookies(self, filepath="jucha_cookies.pkl"): # 保存Cookie到文件
with open(filepath, "wb") as f: # 以二进制写入模式打开文件
pickle.dump(self.cookie, f) # 序列化保存Cookie
save_pickle_atomic(filepath, self.cookie)
logger.info(f"已保存Cookie到文件: {filepath}")
# 保存到Redis
try:
import redis
from app.config import config
redis_client = redis.Redis(
host=config.REDIS_HOST,
port=config.REDIS_PORT,
password=config.REDIS_PASSWORD,
db=config.REDIS_DB,
decode_responses=True
)
from app.utils.redis_client import get_redis_client
redis_client = get_redis_client(role="standard")
# 将cookie转换为字典
cookie_dict = {}
# 检查self.cookie的类型
@@ -292,25 +296,29 @@ class JC(object): # 聚查网API封装类
def load_cookies(self, filepath="jucha_cookies.pkl"): # 从文件加载Cookie
try: # 尝试加载
with open(filepath, "rb") as f: # 以二进制读取模式打开文件
loaded_cookie = pickle.load(f) # 反序列化加载Cookie
# 检查加载的cookie类型
if isinstance(loaded_cookie, dict):
# 如果是字典转换为RequestsCookieJar
cookie_jar = requests.cookies.RequestsCookieJar()
for name, value in loaded_cookie.items():
cookie_jar.set(name, value)
self.cookie = cookie_jar
else:
self.cookie = loaded_cookie
loaded_cookie = load_pickle_locked(
filepath,
default_factory=requests.cookies.RequestsCookieJar,
)
# 检查加载的cookie类型
if isinstance(loaded_cookie, dict):
# 如果是字典转换为RequestsCookieJar
cookie_jar = requests.cookies.RequestsCookieJar()
for name, value in loaded_cookie.items():
cookie_jar.set(name, value)
self.cookie = cookie_jar
else:
self.cookie = loaded_cookie
except Exception as e: # 加载失败
logger.error(f"加载Cookie失败: {e}")
self.cookie = requests.cookies.RequestsCookieJar() # 创建空的CookieJar
def load_juming_cookies(self, filepath="juming_cookies.pkl"): # 从文件加载聚名网Cookie
try: # 尝试加载
with open(filepath, "rb") as f: # 以二进制读取模式打开文件
self.juming_cookie = pickle.load(f) # 反序列化加载Cookie
self.juming_cookie = load_pickle_locked(
filepath,
default_factory=requests.cookies.RequestsCookieJar,
)
except: # 加载失败
self.juming_cookie = requests.cookies.RequestsCookieJar() # 创建空的CookieJar
@@ -318,7 +326,8 @@ class JC(object): # 聚查网API封装类
params = { # 请求参数
'platform': 'juming', # 平台标识
}
res = self.session.get( # 发送GET请求
res = self._request( # 发送GET请求
"get",
url=f'{self.base_url}/home/login/get_auth_url', # 获取授权URL
params=params, # 请求参数
headers=self.headers, # 请求头
@@ -333,7 +342,8 @@ class JC(object): # 聚查网API封装类
combined_cookies = requests.cookies.RequestsCookieJar()
combined_cookies.update(self.juming_cookie)
combined_cookies.update(self.cookie)
response = self.session.get( # 发送GET请求
response = self._request( # 发送GET请求
"get",
url=url, # 跳转URL
headers=self.headers, # 请求头
cookies=combined_cookies, # 合并后的Cookie
@@ -345,7 +355,8 @@ class JC(object): # 聚查网API封装类
self.cookie[name] = value # 直接赋值覆盖同名Cookie
if response.status_code == 302: # 重定向状态码
url = response.headers['location'] # 获取重定向URL
response = self.session.get( # 发送GET请求
response = self._request( # 发送GET请求
"get",
url=url, # 重定向URL
headers=self.headers, # 请求头
allow_redirects=False # 不自动重定向