This commit is contained in:
mzl
2026-01-12 19:42:43 +08:00
parent 9b3b5c8329
commit 389a10351e
+32 -7
View File
@@ -189,11 +189,36 @@ def write_users_txt(users: List[str]) -> None:
os.replace(tmp, path) os.replace(tmp, path)
def require_browser() -> Browser: async def ensure_browser() -> Browser:
if app_state.browser is None: """按需启动浏览器(懒启动),避免服务启动阶段因为未安装 Chromium 而直接崩溃。"""
raise HTTPException(status_code=500, detail="Browser not ready") if app_state.browser is not None:
return app_state.browser return app_state.browser
# 初始化 playwright
if app_state.playwright is None:
app_state.playwright = await async_playwright().start()
try:
# 这里不强制指定 channel,交给 Playwright 选择已安装的 Chromium
app_state.browser = await app_state.playwright.chromium.launch(
headless=True,
args=[
"--no-sandbox",
"--disable-dev-shm-usage",
],
)
log_manager.append("INFO", "Browser launched (lazy init)")
return app_state.browser
except Exception as e:
# 给出明确的修复提示
msg = (
f"Browser not ready: {e}. "
"请先在运行环境执行:`playwright install chromium`。"
)
log_manager.append("ERROR", msg)
raise HTTPException(status_code=500, detail=msg)
# ========================= # =========================
# Status / Logs # Status / Logs
@@ -279,7 +304,7 @@ async def import_users_from_txt():
total_lines = len(raw_lines) total_lines = len(raw_lines)
browser = require_browser() browser = await ensure_browser()
imported_ids: List[str] = [] imported_ids: List[str] = []
duplicates = 0 duplicates = 0
@@ -379,7 +404,7 @@ async def open_login():
说明:前端 window.open 打开的页面不会影响服务端 Playwright 的登录态。 说明:前端 window.open 打开的页面不会影响服务端 Playwright 的登录态。
正确使用方式:在部署环境(Docker + VNC)里打开 VNC 浏览器扫码登录。 正确使用方式:在部署环境(Docker + VNC)里打开 VNC 浏览器扫码登录。
""" """
browser = require_browser() browser = await ensure_browser()
await auth_manager.open_login_page(browser) await auth_manager.open_login_page(browser)
return { return {
"login_url": config.LOGIN_URL, "login_url": config.LOGIN_URL,
@@ -389,7 +414,7 @@ async def open_login():
@app.post("/api/login/verify") @app.post("/api/login/verify")
async def verify_login(): async def verify_login():
browser = require_browser() browser = await ensure_browser()
ok, msg = await auth_manager.verify_login(browser) ok, msg = await auth_manager.verify_login(browser)
meta = auth_manager.load_auth_meta() meta = auth_manager.load_auth_meta()
return { return {
@@ -421,7 +446,7 @@ async def start_scraping(request: StartRequest, background_tasks: BackgroundTask
raise HTTPException(status_code=400, detail="用户列表为空,请先导入 users.txt") raise HTTPException(status_code=400, detail="用户列表为空,请先导入 users.txt")
# 启动前校验登录态(单账号) # 启动前校验登录态(单账号)
browser = require_browser() browser = await ensure_browser()
ok, msg = await auth_manager.verify_login(browser) ok, msg = await auth_manager.verify_login(browser)
if not ok: if not ok:
raise HTTPException(status_code=400, detail=f"未登录或登录失效:{msg}") raise HTTPException(status_code=400, detail=f"未登录或登录失效:{msg}")