Selenium+ChromeDriver:如何结合DevTools会话与代理认证?
解决方案:同步DevTools层面的代理认证与Fetch拦截
核心原因
当同时使用ChromeDriver的NetworkAuthenticationHandler和DevTools Fetch拦截时,两者的请求处理上下文是分离的:Fetch拦截会接管请求的处理流程,绕过ChromeDriver层面的代理认证逻辑,导致代理服务器要求重新验证,弹出凭证输入框,同时原拦截逻辑失效。直接在代理URL中嵌入账号密码也无法生效,因为Chrome在DevTools拦截模式下会忽略URL中的认证信息。
解决步骤
放弃依赖NetworkAuthenticationHandler,转而在DevTools层面直接添加代理认证头,确保Fetch拦截的请求携带正确的代理凭证,同时按顺序初始化配置:
1. 配置代理(不带认证信息)
启动Chrome时仅指定代理地址和端口,不在URL中嵌入账号密码。
2. 通过DevTools添加代理认证头
利用DevTools的Network.setExtraHTTPHeaders命令,为所有请求添加Proxy-Authorization头,格式为Basic [Base64编码的账号密码]。
3. 初始化Fetch拦截逻辑
在完成代理认证配置后,启用Fetch拦截并绑定请求监听事件,处理Bearer Token的捕获。
Python 代码示例
from selenium import webdriver from selenium.webdriver.chrome.options import Options import base64 # 1. 配置Chrome选项,设置代理(不带认证) chrome_options = Options() chrome_options.add_argument('--proxy-server=http://your-proxy-host:your-proxy-port') driver = webdriver.Chrome(options=chrome_options) # 2. 初始化DevTools Network模块,添加代理认证头 driver.execute_cdp_cmd('Network.enable', {}) # 生成Base64编码的代理凭证 proxy_username = "your-proxy-username" proxy_password = "your-proxy-password" auth_encoded = base64.b64encode(f"{proxy_username}:{proxy_password}".encode()).decode() # 设置全局代理认证头 driver.execute_cdp_cmd('Network.setExtraHTTPHeaders', { 'headers': { 'Proxy-Authorization': f'Basic {auth_encoded}' } }) # 3. 配置Fetch拦截,捕获Bearer Token def handle_paused_request(request): # 从请求头中提取Bearer Token request_headers = request['request']['headers'] if 'Authorization' in request_headers: auth_header = request_headers['Authorization'] if auth_header.startswith('Bearer '): bearer_token = auth_header.split(' ')[1] print(f"捕获到Bearer Token: {bearer_token}") # 继续执行请求 driver.execute_cdp_cmd('Fetch.continueRequest', {'requestId': request['requestId']}) # 启用Fetch拦截,拦截所有请求的Request阶段 driver.execute_cdp_cmd('Fetch.enable', { 'patterns': [{'urlPattern': '*', 'requestStage': 'Request'}] }) # 绑定请求暂停事件的处理函数 driver.add_event_listener('Fetch.requestPaused', handle_paused_request) # 访问目标影院网站 driver.get("https://target-cinema-site.com") # 后续操作... driver.quit()
关键注意事项
- 认证头格式正确性:确保
Proxy-Authorization头使用Basic前缀,且账号密码的Base64编码无换行或多余字符。 - 初始化顺序:必须先启用
Network模块并设置认证头,再启用Fetch拦截,避免请求在配置完成前发出导致认证失败。 - 拦截范围:可通过调整
Fetch.enable中的urlPattern参数,仅拦截目标影院网站的API请求,减少不必要的性能开销。
内容的提问来源于stack exchange,提问作者Kjensen
相关产品推荐
相关产品推荐

