Python Selenium如何直接获取并存储完整的JSON响应?
问题背景
你目前使用Selenium获取页面源码,但只能拿到HTML结构,无法直接得到完整的目标JSON数据。你的示例代码如下:
from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options import time options = Options() options.add_argument("--disable-blink-features=AutomationControlled") #options.headless = True driver = webdriver.Chrome('C:/Users/Amanr/Downloads/chromedriver_win32 v106/chromedriver', options=options) driver.get("https://www.") time.sleep(5) res = driver.execute_script('''window.open('https://',"_blank");''') main_window = driver.window_handles[1] driver.switch_to.window(main_window) ps = driver.page_source print(ps)
你期望获取的完整JSON格式如下:
{"identifier":"OPTIDXBANKNIFTY27-10-2022CE41200.00","name":"BANKNIFTY","grapthData":[[1666689300000,359.2],[1666689301000,386.35],[1666689302000,393.45],[1666689303000,397.05],[1666689304000,385.8],[1666689305000,383.25],[1666689306000,378.95],[1666689307000,370.45],[1666689308000,369.15],[1666689309000,372.3],[1666689310000,383.75],[1666689311000,391.65],[1666689312000,400.9],[1666689313000,393.85],[1666689314000,402.7],[1666689315000,397.2],[1666689316000,391.5],[1666689317000,391.95],[1666689318000,391.85],[1666689319000,385.4],[1666689350000,380.55],[1666689351000,380.25],[1666689352000,377.15],[1666689353000,376.1],[1666689354000,373.85],[1666689355000,370
解决方案
1. 直接抓取API请求(最推荐)
页面的图表数据几乎都是通过后台API接口异步加载的,你可以跳过Selenium,直接用requests库请求对应的API,这样能直接拿到完整的JSON响应:
- 操作步骤:打开浏览器开发者工具(F12)→ 切换到「网络」标签→ 刷新页面,筛选「XHR」或「Fetch」类型的请求,找到返回目标JSON的接口,复制其URL、请求头和参数。
- 示例代码:
import requests import json # 替换为实际的API地址和请求头 url = "https://example.com/api/chart-data" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36", # 若需要其他认证头(如Cookie、Authorization),一并添加 } response = requests.get(url, headers=headers) if response.status_code == 200: json_data = response.json() print(json.dumps(json_data, indent=2)) else: print(f"请求失败,状态码:{response.status_code}")
2. 从页面DOM中提取已加载的JSON数据
如果页面将JSON数据嵌入在<script>标签中(比如window.chartData = {...}这类形式),可以用Selenium定位该标签并提取内容:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import json import time options = Options() options.add_argument("--disable-blink-features=AutomationControlled") driver = webdriver.Chrome('C:/Users/Amanr/Downloads/chromedriver_win32 v106/chromedriver', options=options) driver.get("目标页面URL") # 等待页面加载完成 time.sleep(5) # 定位包含JSON数据的script标签,替换为实际的选择器 script_tag = driver.find_element(By.XPATH, "//script[contains(text(), 'chartData')]") script_content = script_tag.get_attribute('textContent') # 提取JSON部分(假设格式是window.chartData = {...};) json_str = script_content.split('window.chartData = ')[1].split(';')[0] json_data = json.loads(json_str) print(json.dumps(json_data, indent=2)) driver.quit()
3. 通过Selenium捕获网络请求日志
配置Chrome浏览器开启性能日志,过滤出目标API的响应内容:
from selenium import webdriver from selenium.webdriver.chrome.options import Options import json import base64 import time options = Options() options.add_argument("--disable-blink-features=AutomationControlled") # 开启性能日志 options.set_capability('goog:loggingPrefs', {'performance': 'ALL'}) driver = webdriver.Chrome('C:/Users/Amanr/Downloads/chromedriver_win32 v106/chromedriver', options=options) driver.get("目标页面URL") time.sleep(5) # 获取性能日志 logs = driver.get_log('performance') for log in logs: log_json = json.loads(log['message']) message = log_json['message'] # 过滤出响应类型的日志,且包含目标API关键词 if message['method'] == 'Network.responseReceived' and 'chart' in message['params']['response']['url']: request_id = message['params']['requestId'] # 获取响应体 response_body = driver.execute_cdp_cmd('Network.getResponseBody', {'requestId': request_id}) if response_body['base64Encoded']: json_data = json.loads(base64.b64decode(response_body['body'])) else: json_data = json.loads(response_body['body']) print(json.dumps(json_data, indent=2)) break driver.quit()
注意事项
- 部分API接口可能需要携带特定的Cookie、Token或请求参数才能正常返回数据,需确保请求头和参数与浏览器一致。
- 若API有签名机制,可能需要分析签名生成逻辑后再构造请求。
内容的提问来源于stack exchange,提问作者Zac

