feat: stabilize multi-region runtime sync and worker orchestration
This commit is contained in:
@@ -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 # 不自动重定向
|
||||
|
||||
Reference in New Issue
Block a user