fix: tolerate transient collect login checks

This commit is contained in:
chengma
2026-07-08 18:24:07 +08:00
parent 2ff7ef3678
commit 45600c137b
5 changed files with 321 additions and 11 deletions
+80 -6
View File
@@ -1185,6 +1185,9 @@ class ApplyWorker(BaseWorker):
class CollectWorker(BaseWorker):
"""Collect old title and cover for imported tasks."""
LOGIN_CHECK_ATTEMPTS = 3
LOGIN_CHECK_RETRY_DELAY_SECONDS = 2.0
def __init__(
self,
tasks,
@@ -1298,8 +1301,8 @@ class CollectWorker(BaseWorker):
self._emit_progress(done, total, collected, skipped, failed)
continue
status = self._login_status(account)
if not status.get("logged_in"):
status = self._confirmed_login_status(account, context="midrun", task=task)
if self._is_definitive_logged_out(status):
alias = str(task.alias).strip()
skipped += 1
done += 1
@@ -1319,6 +1322,16 @@ class CollectWorker(BaseWorker):
)
self._emit_progress(done, total, collected, skipped, failed)
continue
if not status.get("logged_in"):
self._log_run_event(
"step=login_check result=uncertain detail=任务 {task_id} 商品 {item_id} 登录状态检测暂时不稳定,继续尝试采集当前商品: {detail}".format(
task_id=task.id,
item_id=task.item_id,
detail=self._login_status_detail(status),
),
task=task,
level="warning",
)
started = time.monotonic()
current_step = "db_write"
@@ -1488,8 +1501,13 @@ class CollectWorker(BaseWorker):
f"step=login_check result=start detail=账号 {account.alias}",
level="info",
)
status = self._login_status(account)
if not status.get("logged_in"):
status = self._confirmed_login_status(account, context="preflight")
if status.get("logged_in"):
self._log_run_event(
f"step=login_check result=success detail=账号 {account.alias}",
level="info",
)
elif self._is_definitive_logged_out(status):
reason = self._login_skip_reason(status)
self._log_run_event(
f"step=login_check result=blocked detail=账号 {account.alias} {reason}",
@@ -1500,8 +1518,11 @@ class CollectWorker(BaseWorker):
)
else:
self._log_run_event(
f"step=login_check result=success detail=账号 {account.alias}",
level="info",
"step=login_check result=uncertain detail=账号 {alias} 登录状态检测暂时不稳定,继续进入采集流程: {detail}".format(
alias=account.alias,
detail=self._login_status_detail(status),
),
level="warning",
)
info = {
"launched_accounts": launched,
@@ -1548,6 +1569,59 @@ class CollectWorker(BaseWorker):
"reason": f"LOGIN_CHECK_FAILED: {exc}",
}
def _confirmed_login_status(self, account, context, task=None):
last_status = {}
for attempt in range(1, self.LOGIN_CHECK_ATTEMPTS + 1):
status = dict(self._login_status(account) or {})
status["login_check_attempts"] = attempt
last_status = status
if status.get("logged_in") or self._is_definitive_logged_out(status):
return status
if attempt < self.LOGIN_CHECK_ATTEMPTS:
self._log_run_event(
"step=login_check result=retry detail=账号 {alias} 第{attempt}/{total}次登录检测暂不确定,{delay:g}秒后重试: {detail}".format(
alias=getattr(account, "alias", ""),
attempt=attempt,
total=self.LOGIN_CHECK_ATTEMPTS,
delay=self.LOGIN_CHECK_RETRY_DELAY_SECONDS,
detail=self._login_status_detail(status),
),
task=task,
level="warning",
)
time.sleep(self.LOGIN_CHECK_RETRY_DELAY_SECONDS)
last_status["login_check_uncertain"] = True
self._write_diagnostic_log(
"采集登录检测暂不确定",
level="WARNING",
step="login_check",
task=task,
payload={
"context": context,
"alias": getattr(account, "alias", None),
"reason": last_status.get("reason"),
"url": last_status.get("url"),
"cookie_names": list(last_status.get("cookie_names") or []),
"attempts": last_status.get("login_check_attempts"),
},
)
return last_status
def _is_definitive_logged_out(self, status):
reason = str((status or {}).get("reason") or "").strip()
url = str((status or {}).get("url") or "").lower()
return reason.startswith("LOGIN_PAGE") or (
"accounts.shopee." in url and "/seller/login" in url
)
def _login_status_detail(self, status):
status = status or {}
reason = status.get("reason") or "未知原因"
url = status.get("url") or "未知URL"
cookie_names = [str(name) for name in (status.get("cookie_names") or []) if name]
cookie_text = ",".join(sorted(cookie_names)) if cookie_names else "未读到登录Cookie"
return f"原因={reason},URL={url},Cookie名称={cookie_text}"
def _login_skip_reason(self, status):
reason = status.get("reason")
return f"账号未登录: {reason}" if reason else "账号未登录"