From 2b461c2aea7fe260f6e3e53750055d20a86aa433 Mon Sep 17 00:00:00 2001 From: hjq <770690987@qq.com> Date: Fri, 12 Jun 2026 17:47:07 +0800 Subject: [PATCH] =?UTF-8?q?Dockerfile=20=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser_login/login.py | 36 +++++++++++++++++++++++++++++++++++- debug-docker-chromium-404.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 debug-docker-chromium-404.md diff --git a/browser_login/login.py b/browser_login/login.py index 2f11d9f..57ad04a 100644 --- a/browser_login/login.py +++ b/browser_login/login.py @@ -5,9 +5,11 @@ ERP 登录模块 - DrissionPage import os import time import datetime +import urllib.request from pathlib import Path from dotenv import load_dotenv from DrissionPage import ChromiumPage, ChromiumOptions +from DrissionPage._base.chromium import handle_options # ── 加载 .env ───────────────────────────────────────────────────────────────── load_dotenv(Path(__file__).parent / ".env") @@ -98,10 +100,42 @@ def get_page(headless: bool = False, port: int = 9222) -> ChromiumPage: # 本地开发环境:使用固定端口,方便复用 co.set_local_port(port) + # #region debug-point A:drission-target + opt = handle_options(co) + log( + "INFO", + "[DEBUG] Chromium 连接参数: " + f"address={opt.address or ''}, " + f"browser_path={opt.browser_path or ''}, " + f"auto_port={opt.is_auto_port}, " + f"headless={opt.is_headless}, " + f"user_data_path={getattr(opt, 'user_data_path', '') or ''}" + ) + log( + "INFO", + "[DEBUG] Chromium 启动参数: " + + " | ".join(opt.arguments) + ) + # #endregion + try: - page = ChromiumPage(co) + page = ChromiumPage(opt) return page except Exception as e: + # #region debug-point B:devtools-http-probe + if opt.address: + for endpoint in ("json/version", "json/list"): + url = f"http://{opt.address}/{endpoint}" + try: + with urllib.request.urlopen(url, timeout=2) as resp: + body = resp.read().decode("utf-8", errors="replace") + log("WARN", f"[DEBUG] DevTools 探测 {url} -> HTTP {resp.status}") + log("WARN", f"[DEBUG] DevTools 响应体 {endpoint}: {body[:1000]}") + except Exception as probe_err: + log("WARN", f"[DEBUG] DevTools 探测失败 {url}: {probe_err}") + else: + log("WARN", "[DEBUG] DevTools 探测跳过:address 为空") + # #endregion log("ERR", f"浏览器初始化失败: {e}") raise diff --git a/debug-docker-chromium-404.md b/debug-docker-chromium-404.md new file mode 100644 index 0000000..89d8216 --- /dev/null +++ b/debug-docker-chromium-404.md @@ -0,0 +1,29 @@ +# [OPEN] docker-chromium-404 + +## 症状 +- Docker 生产环境中,发料单明细增量同步启动浏览器后报错:`Handshake status 404 Not Found` + +## 当前现象 +- 已确认不是多 worker 竞争导致的旧症状。 +- 已确认 `DrissionPage` 在 Docker 中进入了自动端口模式。 +- 当前需要采集 Chromium 实际调试地址、`/json/version` 返回内容、以及握手前的连接目标。 + +## 初始假设 +- 假设 1:Chromium 虽然启动了,但 DevTools HTTP 接口没有真正暴露在 `127.0.0.1:`。 +- 假设 2:Chromium 暴露的并不是标准 DevTools Browser WebSocket 地址,DrissionPage 连到了错误的 ws 路径。 +- 假设 3:容器内存在反向代理/网关拦截,导致本地调试端口请求拿到 HTML 404 页面。 +- 假设 4:当前 Chromium 启动参数与 Debian slim 镜像内核能力不兼容,浏览器进程启动不完整但未直接抛出更明确异常。 +- 假设 5:DrissionPage 在当前版本下对 Docker 中的 `headless=new` 或自动端口流程存在兼容性问题。 + +## 计划 +- 第一步:只加调试插桩,不改业务逻辑。 +- 第二步:让用户在 Docker 中复现,回收调试日志。 +- 第三步:根据证据确认根因后,再做最小修复。 + +## 已完成 +- 已在 `browser_login/login.py` 的 `get_page()` 增加调试插桩。 +- 插桩会输出: + - DrissionPage 最终计算的 `address` + - Chromium 实际 `browser_path` + - 启动参数列表 + - 握手失败后对 `http://
/json/version` 与 `http://
/json/list` 的探测结果