SeleniumWire修改HTTP请求头失效问题排查与解决求助
问题:SeleniumWire修改请求头无效的排查与解决
我尝试用SeleniumWire修改HTTP请求头,但执行代码后没有效果,希望能像ModHeader扩展那样,每次访问都修改用户相关请求头信息。
原执行代码
import time import os from seleniumwire import webdriver from selenium.webdriver.chrome.options import Options driver = webdriver.Chrome() def interceptor(request): request.headers['User-Agent'] = 'Mozilla/6.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' request.headers['sec-ch-ua'] = '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"' request.headers['sec-ch-ua-mobile'] = '?0' request.headers['sec-ch-ua-platform'] = 'os' driver.request_interceptor = interceptor driver.get("https://google.com") for request in driver.requests: print(request.headers) print(request.response) time.sleep(500)
当前问题现象
执行代码后,输出的请求头中同时存在原浏览器的默认头(如Chrome 111版本的User-Agent、sec-ch-ua系列头)和自定义设置的头,自定义头仅被追加,未完全替换原有头,导致修改无效。
排查原因
- 浏览器自动补充头:Chrome会在SeleniumWire拦截器执行后,自动添加或补充
sec-ch-ua系列细分头(如sec-ch-ua-full-version),这些头不受拦截器控制,保留浏览器默认值。 - 头未删除直接覆盖:拦截器仅直接设置新头值,未删除原有同名头,导致新旧头共存。
- 参数值不合法:设置的
sec-ch-ua-platform值为os不符合规范,浏览器会忽略该设置,继续使用自身平台信息。
解决方案
方案一:改进拦截器,删除原有头再设置新值
修改拦截器逻辑,先删除原有同名请求头,再设置新值,同时修正合法的平台参数:
import time import os from seleniumwire import webdriver from selenium.webdriver.chrome.options import Options def interceptor(request): # 遍历并删除原有需替换的请求头(忽略大小写) target_headers = ['user-agent', 'sec-ch-ua', 'sec-ch-ua-mobile', 'sec-ch-ua-platform'] for key in list(request.headers.keys()): if key.lower() in target_headers: del request.headers[key] # 设置合法的新请求头 request.headers['User-Agent'] = 'Mozilla/6.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' request.headers['sec-ch-ua'] = '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"' request.headers['sec-ch-ua-mobile'] = '?0' request.headers['sec-ch-ua-platform'] = '"Linux"' # 修正为合法的平台标识 options = Options() driver = webdriver.Chrome(options=options) driver.request_interceptor = interceptor driver.get("https://google.com") for request in driver.requests: print(request.headers) print(request.response) time.sleep(500)
方案二:结合Chrome启动参数强制覆盖(更彻底)
通过Chrome启动参数直接设置UA及相关头,从根源上避免浏览器自动补充默认值,再配合拦截器确保所有请求都生效:
import time import os from seleniumwire import webdriver from selenium.webdriver.chrome.options import Options def interceptor(request): # 确保拦截器同步修改头,避免遗漏请求 target_headers = ['user-agent', 'sec-ch-ua', 'sec-ch-ua-mobile', 'sec-ch-ua-platform'] for key in list(request.headers.keys()): if key.lower() in target_headers: del request.headers[key] request.headers['User-Agent'] = 'Mozilla/6.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36' request.headers['sec-ch-ua'] = '"Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"' request.headers['sec-ch-ua-mobile'] = '?0' request.headers['sec-ch-ua-platform'] = '"Linux"' options = Options() # 添加Chrome启动参数,强制设置UA及相关头 options.add_argument('--user-agent=Mozilla/6.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36') options.add_argument('--sec-ch-ua="Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"') options.add_argument('--sec-ch-ua-platform="Linux"') options.add_argument('--sec-ch-ua-mobile=?0') driver = webdriver.Chrome(options=options) driver.request_interceptor = interceptor driver.get("https://google.com") for request in driver.requests: print(request.headers) print(request.response) time.sleep(500)
验证效果
执行修改后的代码,打印请求头时会发现原有默认头已被完全替换,仅保留自定义设置的头信息,实现类似ModHeader的持久修改效果。
内容的提问来源于stack exchange,提问作者masoud fallah
相关产品推荐
相关产品推荐

