|
9 | 9 | import logging |
10 | 10 | import os |
11 | 11 | import re |
| 12 | +from urllib.parse import urlsplit, urlunsplit |
12 | 13 |
|
13 | 14 | log = logging.getLogger(__name__) |
14 | 15 |
|
|
24 | 25 | ) |
25 | 26 |
|
26 | 27 |
|
| 28 | +def _rewrite_loopback_proxy(proxy: str) -> str: |
| 29 | + """Map a host-loopback proxy to Docker Desktop's host gateway when requested.""" |
| 30 | + replacement = str(os.getenv("SOLVER_LOOPBACK_PROXY_HOST") or "").strip() |
| 31 | + if not proxy or not replacement: |
| 32 | + return proxy |
| 33 | + |
| 34 | + try: |
| 35 | + parts = urlsplit(proxy) |
| 36 | + except ValueError: |
| 37 | + return proxy |
| 38 | + if parts.hostname not in {"127.0.0.1", "localhost", "::1"}: |
| 39 | + return proxy |
| 40 | + |
| 41 | + userinfo = parts.netloc.rsplit("@", 1)[0] + "@" if "@" in parts.netloc else "" |
| 42 | + host = f"[{replacement}]" if ":" in replacement and not replacement.startswith("[") else replacement |
| 43 | + port = f":{parts.port}" if parts.port is not None else "" |
| 44 | + return urlunsplit((parts.scheme, f"{userinfo}{host}{port}", parts.path, parts.query, parts.fragment)) |
| 45 | + |
| 46 | + |
27 | 47 | async def resolve_selector(page, selector: str, timeout: int = 10000): |
28 | 48 | """Resolve a selector string to a Playwright locator. |
29 | 49 |
|
@@ -86,12 +106,15 @@ def browser_kwargs(prefix: str, proxy: str = None) -> dict: |
86 | 106 | the interactive-checkbox solvers (recaptcha/hcaptcha) default headless=0. |
87 | 107 | """ |
88 | 108 | default_headless = "1" if prefix == "TURNSTILE" else "0" |
89 | | - kw = {"humanize": True, |
90 | | - "headless": os.getenv(f"{prefix}_HEADLESS", default_headless) != "0"} |
| 109 | + headless = os.getenv(f"{prefix}_HEADLESS", default_headless) != "0" |
| 110 | + kw = {"humanize": True, "headless": headless} |
| 111 | + if not headless and os.getenv(f"{prefix}_HIDE_WINDOW") == "1": |
| 112 | + kw["args"] = ["--window-position=-32000,-32000", "--window-size=1280,900"] |
| 113 | + kw["_suppress_maximize"] = True |
91 | 114 | configured_proxy = str(proxy or os.getenv(f"{prefix}_PROXY") or "").strip() |
92 | 115 | if configured_proxy: |
93 | | - kw["proxy"] = configured_proxy |
94 | | - if os.getenv(f"{prefix}_GEOIP") == "1": |
| 116 | + kw["proxy"] = _rewrite_loopback_proxy(configured_proxy) |
| 117 | + if configured_proxy and os.getenv(f"{prefix}_GEOIP") == "1": |
95 | 118 | kw["geoip"] = True |
96 | 119 | return kw |
97 | 120 |
|
|
0 commit comments