From a412cabce70dd264ba19c6c926aab7406ccebe0f Mon Sep 17 00:00:00 2001 From: hjq <770690987@qq.com> Date: Tue, 23 Jun 2026 18:10:01 +0800 Subject: [PATCH] =?UTF-8?q?BOM=E5=8F=91=E6=96=99=E5=AF=B9=E6=AF=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- browser_login/login.py | 83 ++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 51 deletions(-) diff --git a/browser_login/login.py b/browser_login/login.py index 1519602..333ed9c 100644 --- a/browser_login/login.py +++ b/browser_login/login.py @@ -50,56 +50,34 @@ def patch_drission_ws_handshake() -> None: return def resilient_create_connection(address, **kwargs): - # 终极暴力破解法:移除所有可能导致 Chrome 安全校验失败的头 - base_kwargs = dict(kwargs) - - # 强制禁用代理,防止请求被容器内的网络规则重定向 - no_proxy_hosts = ["127.0.0.1", "localhost", "::1"] - base_kwargs["http_no_proxy"] = no_proxy_hosts - base_kwargs["http_proxy_host"] = None - base_kwargs["http_proxy_port"] = None - - # 提取目标端口,用于构造合法的 Host 头 - try: - port = address.split(":")[2].split("/")[0] - except IndexError: - port = "9222" - - # Chrome 149 增强了 DevTools 的安全校验。 - # Host header 必须是 IP 地址或 localhost,且必须包含端口号! - candidate_kwargs = [ - # 策略1:最标准的 localhost 组合,带端口 - { - **base_kwargs, - "suppress_origin": False, - "header": [f"Host: 127.0.0.1:{port}", "Origin: http://127.0.0.1"] - }, - # 策略2:最原始、最干净的连接方式(类似 curl) - { - **base_kwargs, - "suppress_origin": True, - "header": [] - }, - # 策略3:伪装成 localhost 带端口 - { - **base_kwargs, - "suppress_origin": False, - "header": [f"Host: localhost:{port}", "Origin: http://localhost"] - } + kwargs = dict(kwargs) + + # 禁止 websocket-client 使用代理 + kwargs["http_no_proxy"] = [ + "127.0.0.1", + "localhost", + "::1" ] - - last_err = None - for candidate in candidate_kwargs: - try: - # 强制使用 127.0.0.1,因为在 Docker 内 localhost 可能解析异常 - target_url = address.replace("localhost", "127.0.0.1") - return raw_ws_create_connection(target_url, **candidate) - except WebSocketBadStatusException as ws_err: - last_err = ws_err - except Exception as other_err: - last_err = other_err - break - raise last_err + kwargs["http_proxy_host"] = None + kwargs["http_proxy_port"] = None + + # 删除 DrissionPage 可能传入的 header + kwargs.pop("header", None) + kwargs.pop("host", None) + kwargs.pop("origin", None) + + target_url = address.replace( + "localhost", + "127.0.0.1" + ) + + log("INFO", f"[DEBUG] WS URL: {target_url}") + log("INFO", f"[DEBUG] WS KWARGS: {kwargs}") + + return raw_ws_create_connection( + target_url, + **kwargs + ) if is_linux_env(): dp_driver_module.create_connection = resilient_create_connection @@ -276,7 +254,6 @@ def get_page(headless: bool = False, port: int = 9222) -> ChromiumPage: co.set_argument("--disable-software-rasterizer") co.set_argument("--remote-allow-origins=*") co.set_argument("--remote-debugging-address=127.0.0.1") - co.set_argument("--disable-web-security") co.set_argument("--ignore-certificate-errors") co.set_argument("--proxy-server=direct://") co.set_argument("--proxy-bypass-list=*") @@ -477,5 +454,9 @@ if __name__ == "__main__": except KeyboardInterrupt: log("INFO", "用户中断") finally: - page.quit() + try: + if page: + page.quit() + except Exception: + pass log("INFO", "浏览器已关闭")