feat: 极验验证默认无限重试,由登录整体超时兜底
- max_proxy_retries 默认值从10改为0(无限重试) - _solve_geetest 增加 deadline 参数,超时则主动退出 - login() 计算 deadline 并传递给极验验证 - 前端/Schema/Service 默认值同步更新
This commit is contained in:
+10
-3
@@ -72,7 +72,7 @@ class DouyuLogin:
|
|||||||
proxy_api_url: Optional[str] = None,
|
proxy_api_url: Optional[str] = None,
|
||||||
timeout: tuple[float, float] = REQUEST_TIMEOUT,
|
timeout: tuple[float, float] = REQUEST_TIMEOUT,
|
||||||
max_geetest_retries: int = 5,
|
max_geetest_retries: int = 5,
|
||||||
max_proxy_retries: int = 10,
|
max_proxy_retries: int = 0,
|
||||||
max_login_retries: int = 3,
|
max_login_retries: int = 3,
|
||||||
max_total_time: float = 300,
|
max_total_time: float = 300,
|
||||||
whitelist_uid: str = "",
|
whitelist_uid: str = "",
|
||||||
@@ -328,6 +328,7 @@ class DouyuLogin:
|
|||||||
"""
|
"""
|
||||||
logger.info(f"开始登录账号: {self.account.username}")
|
logger.info(f"开始登录账号: {self.account.username}")
|
||||||
start_time = time.monotonic()
|
start_time = time.monotonic()
|
||||||
|
deadline = start_time + self.max_total_time
|
||||||
|
|
||||||
for attempt in range(1, self.max_login_retries + 1):
|
for attempt in range(1, self.max_login_retries + 1):
|
||||||
elapsed = time.monotonic() - start_time
|
elapsed = time.monotonic() - start_time
|
||||||
@@ -347,7 +348,7 @@ class DouyuLogin:
|
|||||||
|
|
||||||
# 2️⃣ 极验 fullpage 验证
|
# 2️⃣ 极验 fullpage 验证
|
||||||
logger.info("步骤2: 极验 fullpage 验证...")
|
logger.info("步骤2: 极验 fullpage 验证...")
|
||||||
validate, seccode = self._solve_geetest(gt, challenge)
|
validate, seccode = self._solve_geetest(gt, challenge, deadline=deadline)
|
||||||
|
|
||||||
# 3️⃣ 第二次登录(带极验)
|
# 3️⃣ 第二次登录(带极验)
|
||||||
logger.info("步骤3: 第二次登录(带极验验证)...")
|
logger.info("步骤3: 第二次登录(带极验验证)...")
|
||||||
@@ -454,7 +455,7 @@ class DouyuLogin:
|
|||||||
|
|
||||||
return gt, challenge, code_token, self.session.cookies.get_dict()
|
return gt, challenge, code_token, self.session.cookies.get_dict()
|
||||||
|
|
||||||
def _solve_geetest(self, gt: str, challenge: str) -> Tuple[str, str]:
|
def _solve_geetest(self, gt: str, challenge: str, deadline: float = 0) -> Tuple[str, str]:
|
||||||
"""
|
"""
|
||||||
解决极验 fullpage 验证(带重试机制)
|
解决极验 fullpage 验证(带重试机制)
|
||||||
|
|
||||||
@@ -465,6 +466,8 @@ class DouyuLogin:
|
|||||||
Args:
|
Args:
|
||||||
gt: 极验gt参数
|
gt: 极验gt参数
|
||||||
challenge: 极验challenge参数(第一次登录返回的)
|
challenge: 极验challenge参数(第一次登录返回的)
|
||||||
|
deadline: 登录整体超时截止时间(monotonic),0=不限
|
||||||
|
challenge: 极验challenge参数(第一次登录返回的)
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
(validate, seccode)
|
(validate, seccode)
|
||||||
@@ -479,6 +482,10 @@ class DouyuLogin:
|
|||||||
_SOFT_FAIL_THRESHOLD = 2 # 同一代理连续临时失败2次才换
|
_SOFT_FAIL_THRESHOLD = 2 # 同一代理连续临时失败2次才换
|
||||||
|
|
||||||
for attempt in range(max_attempts):
|
for attempt in range(max_attempts):
|
||||||
|
# 超时兜底:极验验证不应超过登录整体时间上限
|
||||||
|
if deadline and time.monotonic() > deadline:
|
||||||
|
raise ValueError(f"极验验证超时(登录整体时间耗尽)")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.max_proxy_retries > 0:
|
if self.max_proxy_retries > 0:
|
||||||
logger.info(f"极验验证尝试 {attempt + 1}/{max_attempts}")
|
logger.info(f"极验验证尝试 {attempt + 1}/{max_attempts}")
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class AccountOut(BaseModel):
|
|||||||
class LoginBatchRequest(BaseModel):
|
class LoginBatchRequest(BaseModel):
|
||||||
account_ids: list[int]
|
account_ids: list[int]
|
||||||
max_geetest_retries: int = 5
|
max_geetest_retries: int = 5
|
||||||
max_proxy_retries: int = 10 # 代理切换次数,0=无限切换直到成功
|
max_proxy_retries: int = 0 # 代理切换次数,0=无限切换直到成功
|
||||||
max_login_retries: int = 3 # 登录整体重试次数(换代理从头重跑)
|
max_login_retries: int = 3 # 登录整体重试次数(换代理从头重跑)
|
||||||
max_total_time: float = 300 # 单账号登录总时长上限(秒),超时则放弃
|
max_total_time: float = 300 # 单账号登录总时长上限(秒),超时则放弃
|
||||||
concurrency: int = 3 # 并发数,1-10
|
concurrency: int = 3 # 并发数,1-10
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class LoginBatchRunner:
|
|||||||
created_by: int,
|
created_by: int,
|
||||||
creator_permissions: list[str],
|
creator_permissions: list[str],
|
||||||
max_geetest_retries: int = 5,
|
max_geetest_retries: int = 5,
|
||||||
max_proxy_retries: int = 10,
|
max_proxy_retries: int = 0,
|
||||||
max_login_retries: int = 3,
|
max_login_retries: int = 3,
|
||||||
max_total_time: float = 300,
|
max_total_time: float = 300,
|
||||||
proxy_config: Optional[ProxyConfigModel] = None,
|
proxy_config: Optional[ProxyConfigModel] = None,
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export default function LoginTasksPage() {
|
|||||||
});
|
});
|
||||||
const [maxProxyRetries, setMaxProxyRetries] = useState(() => {
|
const [maxProxyRetries, setMaxProxyRetries] = useState(() => {
|
||||||
const v = localStorage.getItem('login_max_proxy_retries');
|
const v = localStorage.getItem('login_max_proxy_retries');
|
||||||
return v ? Math.max(0, Number(v) || 10) : 10;
|
return v ? Math.max(0, Number(v) || 0) : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 值变化时自动持久化
|
// 值变化时自动持久化
|
||||||
|
|||||||
Reference in New Issue
Block a user