Files
boss_dp/worker/tasks/check_login.py
ddrwode 530d7fe135 haha
2026-02-27 13:56:15 +08:00

150 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
"""
检测 BOSS 直聘账号登录状态任务。
流程:在比特浏览器分组中按名称查找环境 → 打开该浏览器 → 访问 BOSS 聊天页 → 获取 .user-name 文本。
"""
from __future__ import annotations
import asyncio
from typing import Any, Callable, Coroutine, Dict
from common.protocol import TaskType
from worker.tasks.base import BaseTaskHandler
from worker.bit_browser import BitBrowserAPI
from worker.browser_control import connect_browser, human_delay
CHAT_INDEX_URL = "https://www.zhipin.com/web/chat/index"
class CheckLoginHandler(BaseTaskHandler):
"""检测 BOSS 直聘账号是否已登录。"""
task_type = TaskType.CHECK_LOGIN.value
async def execute(
self,
task_id: str,
params: Dict[str, Any],
progress_cb: Callable[[str, str], Coroutine],
) -> Any:
"""
params:
- account_name: str 比特浏览器环境名称(前端传入的 browser_name
- account_id: str 比特浏览器窗口 ID可选优先级高于 name
- bit_api_base: str 比特浏览器 API 地址(可选)
"""
account_name = params.get("account_name", "")
account_id = params.get("account_id", "")
bit_api_base = params.get("bit_api_base", "http://127.0.0.1:54345")
await progress_cb(task_id, f"正在比特浏览器中查找环境: {account_name}...")
result = await asyncio.get_event_loop().run_in_executor(
None,
self._run_sync,
account_name, account_id, bit_api_base,
)
status_text = "已登录" if result["is_logged_in"] else "未登录"
await progress_cb(task_id, f"检测完成: {result['browser_name']}{status_text} ({result['boss_username']})")
return result
def _run_sync(
self,
account_name: str,
account_id: str,
bit_api_base: str,
) -> dict:
"""同步执行(线程池中运行)。"""
bit_api = BitBrowserAPI(bit_api_base)
# ── 1. 在比特浏览器分组中查找匹配的环境 ──
browser_id = account_id
browser_name = account_name
if not browser_id and account_name:
self.logger.info("正在比特浏览器中查找环境: %s", account_name)
# 获取所有浏览器窗口,按名称匹配
all_browsers = bit_api.list_browsers(page_size=200)
matched = None
# 精确匹配
for item in all_browsers:
if item.get("name", "").strip() == account_name.strip():
matched = item
break
# 未精确匹配到则模糊匹配
if not matched:
for item in all_browsers:
name = item.get("name", "").strip().lower()
if account_name.strip().lower() in name:
matched = item
break
if not matched:
raise RuntimeError(
f"在比特浏览器中未找到名为 '{account_name}' 的环境。"
f"当前共 {len(all_browsers)} 个环境,"
f"名称列表: {[b.get('name', '') for b in all_browsers[:10]]}..."
)
browser_id = matched.get("id", "")
browser_name = matched.get("name", account_name)
self.logger.info(
"找到匹配环境: name=%s, id=%s, remark=%s",
browser_name, browser_id, matched.get("remark", ""),
)
if not browser_id:
raise RuntimeError("未指定 account_name 或 account_id无法确定浏览器环境")
# ── 2. 打开该浏览器 ──
cdp_addr, port, browser_id = bit_api.open_browser(browser_id=browser_id)
self.logger.info("已打开浏览器 %s (%s), CDP: %s", browser_name, browser_id, cdp_addr)
# ── 3. 连接浏览器 ──
browser = connect_browser(port=port)
tab = browser.latest_tab
# ── 4. 访问 BOSS 直聘聊天页 ──
tab.get(CHAT_INDEX_URL)
tab.wait.load_start()
human_delay(3.0, 5.0)
# ── 5. 查找 .user-name 元素,判断是否已登录 ──
boss_username = ""
boss_id = ""
is_logged_in = False
try:
user_name_ele = tab.ele("css:.user-name", timeout=10)
if user_name_ele and user_name_ele.text:
boss_username = user_name_ele.text.strip()
is_logged_in = bool(boss_username)
self.logger.info("环境 %s 已登录: %s", browser_name, boss_username)
# 提取 BOSS 直聘用户 IDwindow._PAGE?.uid
try:
uid_result = tab.run_js(
"(function(){try{var p=window._PAGE;if(p&&p.uid)return String(p.uid);}catch(e){}return '';})()"
)
if uid_result is not None and str(uid_result).strip():
boss_id = str(uid_result).strip()
self.logger.info("环境 %s boss_id=%s", browser_name, boss_id)
except Exception as js_err:
self.logger.debug("提取 boss_id 失败: %s", js_err)
else:
self.logger.info("环境 %s 未检测到 .user-name账号未登录", browser_name)
except Exception as e:
self.logger.warning("环境 %s 查找 .user-name 失败: %s", browser_name, e)
return {
"browser_id": browser_id,
"browser_name": browser_name,
"boss_username": boss_username,
"boss_id": boss_id,
"is_logged_in": is_logged_in,
}