使用Python Requests下载Excel时Payload不匹配,报400错误求助
解决requests POST下载Excel返回400的问题
你的代码存在几个关键问题,导致服务器返回400错误,逐一修正如下:
1. 错误的collectionId提取方式
response.content是字节类型,无法直接通过字典键取值。需根据GET请求的返回格式选择解析方式:
- 如果返回JSON格式数据:
# 替换原提取代码 collection_data = response.json() collectionId = collection_data['collectionId']
- 如果返回HTML页面(collectionId嵌在页面脚本中):
import re html_content = response.text match = re.search(r'collectionId:\s*"([^"]+)"', html_content) if match: collectionId = match.group(1) else: raise ValueError("未找到collectionId")
2. 完全复刻浏览器的Payload结构
你当前仅传递了collectionId,但浏览器实际发送的Payload可能包含更多参数(比如截图中的其他字段),必须1:1复刻浏览器的Payload字段和数据类型。例如浏览器发送的Payload是:
{ "collectionId": "xxx", "exportType": "excel", "filters": {} }
就要把所有字段都加入你的payload。
同时要检查请求头是否匹配:
- 若浏览器发送的是
Content-Type: application/json,用json=payload没问题; - 若为
Content-Type: application/x-www-form-urlencoded,需改用data=payload; - 务必带上浏览器请求中的关键头信息,比如
Referer、User-Agent等,示例:
headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Referer": url, "X-Requested-With": "XMLHttpRequest" }
3. 完整修正后的代码示例
import requests import re s = requests.Session() url = "你的目标URL" # 初始化会话,获取页面数据 response = s.get(url) if response.status_code != 200: raise Exception("页面加载失败") # 提取collectionId(根据实际返回内容选择对应方式) # 方式1:返回JSON时使用 # collection_data = response.json() # collectionId = collection_data['collectionId'] # 方式2:返回HTML时使用正则提取 html_content = response.text match = re.search(r'collectionId:\s*"([^"]+)"', html_content) if not match: raise ValueError("未找到collectionId") collectionId = match.group(1) # 完全复刻浏览器的Payload结构 payload = { "collectionId": collectionId, # 添加浏览器Payload里的其他必填字段 "exportType": "excel", "filters": {} } # 带上匹配浏览器的请求头 headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36", "Referer": url, "Content-Type": "application/json" } # 发送请求并保存Excel文件 response = s.post(url, json=payload, headers=headers) if response.status_code == 200: with open("导出数据.xlsx", "wb") as f: f.write(response.content) else: print(f"请求失败,状态码:{response.status_code},错误详情:{response.text}")
额外排查点
- 打印
response.text查看服务器返回的具体错误信息,400状态码通常会明确指出不符合要求的地方; - 用F12开发者工具对比你的请求与浏览器请求的所有参数、头信息、Cookie,确保完全一致;
- 确认POST请求的URL和浏览器使用的URL完全相同,避免路径错误。
内容的提问来源于stack exchange,提问作者Chinthaka
相关产品推荐
相关产品推荐

