根据 UA 补全常见的 sec-ch-* 头。
(user_agent: str)
| 114 | |
| 115 | |
| 116 | def _guess_client_hints_from_user_agent(user_agent: str) -> Dict[str, str]: |
| 117 | """根据 UA 补全常见的 sec-ch-* 头。""" |
| 118 | ua = (user_agent or "").strip() |
| 119 | if not ua: |
| 120 | return {} |
| 121 | |
| 122 | headers: Dict[str, str] = {} |
| 123 | major_match = re.search(r"(?:Chrome|Chromium|Edg|EdgA|EdgiOS)/(\d+)", ua) |
| 124 | is_mobile = any(token in ua for token in ("Android", "iPhone", "iPad", "Mobile")) |
| 125 | headers["sec-ch-ua-mobile"] = "?1" if is_mobile else "?0" |
| 126 | |
| 127 | if "Windows" in ua: |
| 128 | headers["sec-ch-ua-platform"] = '"Windows"' |
| 129 | elif "Macintosh" in ua or "Mac OS X" in ua: |
| 130 | headers["sec-ch-ua-platform"] = '"macOS"' |
| 131 | elif "Android" in ua: |
| 132 | headers["sec-ch-ua-platform"] = '"Android"' |
| 133 | elif "iPhone" in ua or "iPad" in ua: |
| 134 | headers["sec-ch-ua-platform"] = '"iOS"' |
| 135 | elif "Linux" in ua: |
| 136 | headers["sec-ch-ua-platform"] = '"Linux"' |
| 137 | |
| 138 | if major_match: |
| 139 | major = major_match.group(1) |
| 140 | if "Edg/" in ua: |
| 141 | headers["sec-ch-ua"] = ( |
| 142 | f'"Not:A-Brand";v="99", "Microsoft Edge";v="{major}", "Chromium";v="{major}"' |
| 143 | ) |
| 144 | else: |
| 145 | headers["sec-ch-ua"] = ( |
| 146 | f'"Not:A-Brand";v="99", "Google Chrome";v="{major}", "Chromium";v="{major}"' |
| 147 | ) |
| 148 | |
| 149 | return headers |
| 150 | |
| 151 | |
| 152 | def _validate_browser_proxy_url_local(proxy_url: str) -> tuple[bool, Optional[str]]: |
no outgoing calls