feat: CDP 接管开关 + 扫码登录面板 + Docker 部署
- runner: enable_cdp_mode 从硬编码 False 改为系统设置 cdp_enabled。服务器部署下爬虫接管已开启远程调试的 Chrome(默认 9222),复用其 profile 登录态;本机桌面默认仍为关,行为不变 - qrlogin: 新增 CDP 扫码登录。Chrome 在服务器上跑于 Xvfb,show_qrcode 依赖的 PIL 桌面看图程序不存在,二维码无处可显示;改为经 CDP 从页面取出二维码交给 WebUI 渲染。刻意复用 browser.contexts[0](新建 context 是无痕 profile,扫了也白扫),且绝不调用 browser.close()(会连带关掉操作者自己的 Chrome) - webui: 设置页新增扫码面板,替换原本跳到采集页看终端二维码的入口 - Dockerfile / .dockerignore / docker-compose.yml: 服务器部署。host 网络是必需而非图省事——容器里 127.0.0.1:9222 必须落到宿主机回环 - UPSTREAM.md: 补充 gitcode 镜像,用于 GitHub 大包传输必断时补历史
This commit is contained in:
+38
-1
@@ -23,7 +23,7 @@ from typing import Any, Dict, List, Optional
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Query, Response
|
||||
|
||||
from ..monitor import notify, report, service
|
||||
from ..monitor import notify, qrlogin, report, service
|
||||
from ..monitor.db import get_session
|
||||
from ..monitor.platforms import PLATFORM_XHS
|
||||
from ..monitor.settings import (
|
||||
@@ -243,6 +243,43 @@ async def clear_cookie_endpoint(platform: str = Query(default=PLATFORM_XHS)):
|
||||
return {"message": "Cookie cleared"}
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# QR login
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# These drive the browser already listening on the CDP debug port, which is the
|
||||
# same browser -- and therefore the same profile -- that monitor runs attach to.
|
||||
# Scanning once is what makes later unattended runs logged in.
|
||||
|
||||
|
||||
@router.post("/login/qr")
|
||||
async def start_qr_login(platform: str = Query(default=PLATFORM_XHS)):
|
||||
"""Open the login page in the CDP browser and return its QR code.
|
||||
|
||||
A server deployment has no display (Chrome sits under Xvfb), so the code is
|
||||
surfaced here for the operator to scan instead of in a desktop window that
|
||||
does not exist.
|
||||
"""
|
||||
try:
|
||||
return await qrlogin.start(platform)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=400, detail=str(exc))
|
||||
except RuntimeError as exc:
|
||||
raise HTTPException(status_code=502, detail=str(exc))
|
||||
|
||||
|
||||
@router.get("/login/qr")
|
||||
async def get_qr_login():
|
||||
"""Poll the live session: waiting -> success / expired / error."""
|
||||
return await qrlogin.status()
|
||||
|
||||
|
||||
@router.delete("/login/qr")
|
||||
async def cancel_qr_login():
|
||||
"""Drop our tab and stop polling."""
|
||||
return await qrlogin.cancel()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Report
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user