如何程序化捕获、修改并重发含复杂JS的POST请求?
解决方案
Python 实现方式
方法1:Selenium + Chrome DevTools Protocol (CDP)
利用Chrome的DevTools协议直接拦截并修改网络请求,无需额外代理工具,核心步骤如下:
- 初始化Selenium Chrome浏览器,启用CDP网络监听
- 匹配目标POST请求,解析并修改请求体参数
- 构造修改后的请求并发送
示例代码:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import json # 初始化浏览器配置 chrome_options = Options() chrome_options.add_argument("--start-maximized") driver = webdriver.Chrome(options=chrome_options) # 启用网络拦截功能 driver.execute_cdp_cmd("Network.enable", {}) # 定义请求拦截处理逻辑 def handle_intercepted_request(request): # 匹配目标POST请求 if request['method'] == 'POST' and '目标接口路径' in request['url']: # 解析原始请求体 original_body = request['postData'] original_data = json.loads(original_body) # 修改指定字段值 original_data['target_key'] = 'modified_value' modified_body = json.dumps(original_data) # 发送修改后的请求 driver.execute_cdp_cmd("Network.continueInterceptedRequest", { 'interceptionId': request['interceptionId'], 'url': request['url'], 'method': 'POST', 'postData': modified_body, 'headers': request['headers'] }) else: # 放行非目标请求 driver.execute_cdp_cmd("Network.continueInterceptedRequest", { 'interceptionId': request['interceptionId'] }) # 设置全局请求拦截规则 driver.execute_cdp_cmd("Network.setRequestInterception", { 'patterns': [{'urlPattern': '*', 'interceptionStage': 'HeadersReceived'}] }) # 绑定拦截回调 driver.add_cdp_listener("Network.requestIntercepted", handle_intercepted_request) # 执行登录、表单填写流程 driver.get("目标页面URL") # 此处补充登录、表单填写的Selenium代码... # 关闭浏览器 driver.quit()
方法2:mitmproxy + Selenium
mitmproxy是轻量级开源代理工具,可拦截、修改HTTP请求,配合Selenium使用需将浏览器代理指向mitmproxy:
- 编写mitmproxy脚本处理POST请求修改
- 配置Selenium使用mitmproxy代理
- 启动mitmproxy和Selenium完成流程
示例mitmproxy脚本(modify_post.py):
from mitmproxy import http def request(flow: http.HTTPFlow) -> None: # 匹配目标POST接口 if flow.request.method == "POST" and "目标接口路径" in flow.request.pretty_url: # 解析并修改请求体 data = flow.request.json() data['target_key'] = 'modified_value' flow.request.json(data)
启动mitmproxy:
mitmdump -s modify_post.py
Selenium代理配置代码:
from selenium import webdriver from selenium.webdriver.chrome.options import Options chrome_options = Options() # 指向mitmproxy代理地址 chrome_options.add_argument('--proxy-server=http://127.0.0.1:8080') # 忽略自签名证书错误 chrome_options.add_argument('--ignore-certificate-errors') driver = webdriver.Chrome(options=chrome_options) driver.get("目标页面URL") # 此处补充登录、表单填写的Selenium代码... driver.quit()
Node.js (Puppeteer) 实现方式
Puppeteer内置请求拦截API,通过page.setRequestInterception即可快速实现捕获、修改并重发POST请求:
示例代码:
const puppeteer = require('puppeteer'); (async () => { const browser = await puppeteer.launch({ headless: false }); const page = await browser.newPage(); // 启用请求拦截 await page.setRequestInterception(true); page.on('request', (request) => { // 匹配目标POST请求 if (request.method() === 'POST' && request.url().includes('目标接口路径')) { // 解析原始请求体 const originalData = JSON.parse(request.postData()); // 修改指定字段 originalData.target_key = 'modified_value'; const modifiedData = JSON.stringify(originalData); // 发送修改后的请求 request.continue({ postData: modifiedData, headers: request.headers() }); } else { // 放行其他请求 request.continue(); } }); // 执行登录、表单填写流程 await page.goto('目标页面URL'); // 此处补充登录、表单填写的Puppeteer代码... // 关闭浏览器 await browser.close(); })();
注意事项
- 拦截时需精准匹配目标接口路径,避免干扰其他正常请求
- 修改请求体时需保证数据格式(如JSON结构、编码)与原始请求一致
- 使用mitmproxy时需先安装mitmproxy证书,否则浏览器会触发证书错误
内容的提问来源于stack exchange,提问作者Shahriar
相关产品推荐
相关产品推荐

