如何通过Chrome DevTools Protocol获取Network响应内容
基于Chrome DevTools Protocol获取Network响应内容的实现方案
对应参考截图如下:
现有代码的问题
- 未提前启用Network域:CDP协议要求使用对应功能域的接口前,必须先发送
Network.enable指令激活域,否则无法接收网络事件、调用相关方法 - 参数混淆:请求结构中的
id是自定义请求序列号,可随意填入整数,用于匹配请求与返回结果;而Network.getResponseBody必填的requestId参数被遗漏,该值需要从网络请求事件中捕获得到 - 缺少网络事件监听逻辑:直接调用
getResponseBody无法指定要查询的请求,必须先监听网络请求事件,拿到目标请求的唯一requestId后才能调用接口获取响应
前置操作
启动Chrome时开启远程调试端口:
- Windows:
chrome.exe --remote-debugging-port=9222 - Mac:
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --remote-debugging-port=9222 - Linux:
google-chrome --remote-debugging-port=9222
启动后访问http://localhost:9222/json,找到目标页面对应的webSocketDebuggerUrl字段,替换代码中的ws连接地址。
完整可运行代码
import websocket import json from pprint import pprint # 替换为你自己的页面websocket地址 WS_URL = "ws://localhost:9222/devtools/page/5EC90A588BEC2DA0229988D28BA67495" # 可配置你要捕获的请求路径关键词,比如要抓/api/list的请求就填"/api/list" TARGET_REQUEST_PATH = "/api/" def on_message(ws, message): msg = json.loads(message) # 监听响应接收完成事件 if msg.get("method") == "Network.responseReceived": response = msg["params"]["response"] request_id = msg["params"]["requestId"] # 匹配目标请求 if TARGET_REQUEST_PATH in response["url"]: print(f"捕获到目标请求:{response['url']}") # 调用getResponseBody获取响应内容,id填自定义序号即可 ws.send(json.dumps({ "id": 1, "method": "Network.getResponseBody", "params": {"requestId": request_id} })) # 匹配getResponseBody的返回结果 if msg.get("id") == 1: print("响应内容:") pprint(msg["result"]) # 如果是base64编码的二进制内容可以自行解码 # if msg["result"]["base64Encoded"]: # import base64 # content = base64.b64decode(msg["result"]["body"]) ws.close() def on_error(ws, error): print("错误:", error) def on_open(ws): # 开启Network域 ws.send(json.dumps({"id": 2, "method": "Network.enable"})) print("Network域已启用,开始监听请求...") if __name__ == "__main__": ws = websocket.WebSocketApp(WS_URL, on_open=on_open, on_message=on_message, on_error=on_error) ws.run_forever()
注意事项
- 若目标请求在页面打开时已经加载完成,可以在启动脚本后刷新页面触发请求重发,即可捕获到对应请求
- 二进制类响应(图片、文件等)返回的body为base64编码,可根据返回的
base64Encoded字段判断后自行解码
内容的提问来源于stack exchange,提问作者October
相关产品推荐
相关产品推荐

