如何获取内嵌JavaScript游戏的XHR响应并保存为JSON?
解决Unity内嵌游戏XHR响应捕获问题
1. 用Selenium 4 DevTools直接拦截网络响应
Selenium 4及以上版本支持Chrome DevTools协议(CDP),可以直接监听并捕获所有网络请求和完整响应,包括XHR。示例代码(Python):
from selenium import webdriver from selenium.webdriver.chrome.service import Service import json # 初始化浏览器并启用DevTools driver = webdriver.Chrome(service=Service("chromedriver路径")) driver.execute_cdp_cmd("Network.enable", {}) # 存储响应的列表 responses = [] # 监听响应完成事件 def capture_response(response): # 只捕获XHR请求 if response["type"] == "XHR": # 获取完整响应内容 resp_body = driver.execute_cdp_cmd( "Network.getResponseBody", {"requestId": response["requestId"]} ) # 解析并存储 try: response_data = json.loads(resp_body["body"]) responses.append({ "url": response["response"]["url"], "status": response["response"]["status"], "data": response_data }) except: # 非JSON格式的响应单独处理 responses.append({ "url": response["response"]["url"], "status": response["response"]["status"], "raw_body": resp_body["body"] }) # 绑定事件监听 driver.add_cdp_listener("Network.responseReceived", capture_response) # 执行你的游戏操作(比如点击等) # ... 这里放你已有的Selenium操作代码 ... # 操作完成后保存响应到JSON文件 with open("game_xhr_responses.json", "w", encoding="utf-8") as f: json.dump(responses, f, indent=2, ensure_ascii=False) driver.quit()
2. 修复requests/Postman的400错误
400错误几乎都是请求参数/头信息不全导致的,你需要把Selenium浏览器里的所有请求上下文复制到requests里:
- 提取Cookie:用
driver.get_cookies()把浏览器的Cookie转成requests能用的字典格式 - 复制请求头:包括
User-Agent、Referer、X-Requested-With等,甚至一些网站自定义的验证头(比如X-CSRF-Token) - 检查动态参数:有些请求会带动态生成的token(比如存在
localStorage或sessionStorage里),可以用driver.execute_script("return localStorage.getItem('token_key')")提取后加到请求里
示例requests代码:
import requests # 从Selenium提取Cookie cookies = {cookie["name"]: cookie["value"] for cookie in driver.get_cookies()} # 从Selenium提取User-Agent user_agent = driver.execute_script("return navigator.userAgent") headers = { "User-Agent": user_agent, "Referer": driver.current_url, # 其他从浏览器开发者工具里看到的请求头 } # 发送请求 response = requests.get("目标XHR接口URL", headers=headers, cookies=cookies) # 保存响应 with open("response.json", "w", encoding="utf-8") as f: json.dump(response.json(), f, indent=2)
3. 检查是否是WebSocket通信
很多Unity WebGL游戏不用XHR,而是用WebSocket和服务器实时通信。这种情况下,你可以用DevTools监听WebSocket消息:
# 启用WebSocket监听 driver.execute_cdp_cmd("WebSocket.enable", {}) ws_messages = [] def capture_ws_message(message): ws_messages.append({ "type": "send" if message["type"] == "WebSocketFrameSent" else "receive", "data": message["response"]["payloadData"] }) driver.add_cdp_listener("WebSocket.frameSent", capture_ws_message) driver.add_cdp_listener("WebSocket.frameReceived", capture_ws_message) # 执行游戏操作后保存 with open("ws_messages.json", "w", encoding="utf-8") as f: json.dump(ws_messages, f, indent=2)
4. 注入JS钩子捕获响应
如果DevTools方法不好用,可以直接在页面里注入JS代码,拦截fetch或XMLHttpRequest的响应:
# 注入拦截fetch的JS脚本 intercept_script = """ window.gameResponses = []; const originalFetch = window.fetch; window.fetch = async (...args) => { const response = await originalFetch(...args); // 克隆响应以便读取内容 const clonedResp = response.clone(); try { const data = await clonedResp.json(); window.gameResponses.push({ url: args[0], status: response.status, data: data }); } catch {} return response; }; """ driver.execute_script(intercept_script) # 执行游戏操作 # ... # 提取捕获的响应 responses = driver.execute_script("return window.gameResponses") with open("injected_responses.json", "w", encoding="utf-8") as f: json.dump(responses, f, indent=2)
内容的提问来源于stack exchange,提问作者Falk
相关产品推荐
相关产品推荐

