如何自定义特定请求头及顺序以模拟APP合法请求?
解决API请求模拟时的请求头问题
一、彻底移除多余请求头
requests库会自动注入默认请求头(比如Accept、Connection、Accept-Encoding等),要完全只保留指定头,最可靠的方式是跳过requests的默认处理,用更底层的库手动构建请求:
用http.client实现(完全自定义)
import http.client # 按需求定义请求头,用列表存储以控制顺序 custom_headers = [ ("User-Agent", "你的APP真实UA"), ("X-Custom-Header1", "value1"), ("X-Custom-Header2", "value2"), # 其他需要的请求头 ] conn = http.client.HTTPSConnection("api.example.com") # 传入列表格式的headers,严格按定义顺序发送 conn.request("GET", "/api/endpoint", headers=dict(custom_headers)) response = conn.getresponse() print(response.status) print(response.read().decode()) conn.close()
这种方式不会自动添加任何额外请求头,完全由自定义列表控制内容与顺序。
用urllib3实现
import urllib3 # 创建PoolManager时禁用默认头 http = urllib3.PoolManager(headers=None) # Python3.7+普通dict默认有序,直接按需要的顺序定义 custom_headers = { "User-Agent": "你的APP真实UA", "X-Custom-Header1": "value1", "X-Custom-Header2": "value2", } response = http.request("GET", "https://api.example.com/api/endpoint", headers=custom_headers) print(response.status) print(response.data.decode())
通过headers=None避免urllib3自动添加默认头,自定义有序字典控制请求头顺序与内容。
二、严格控制请求头顺序
如果服务端确实校验请求头顺序,http.client是最直接的方案——它接受列表格式的headers,会严格按列表中的顺序发送。也可以用requests的PreparedRequest手动调整:
import requests from requests.models import PreparedRequest url = "https://api.example.com/api/endpoint" # 用列表定义请求头的严格顺序 ordered_headers = [ ("User-Agent", "你的APP真实UA"), ("X-Custom-Header1", "value1"), ("X-Custom-Header2", "value2"), ] req = PreparedRequest() req.prepare_url(url, None) # 替换默认headers为自定义有序字典 req.headers = dict(ordered_headers) # POST请求需额外处理body:req.prepare_body(b"请求体内容", None) with requests.Session() as s: response = s.send(req) print(response.status) print(response.text)
注意:requests发送PreparedRequest时可能仍会自动添加Host头等,若要完全剔除,建议用http.client。
三、403错误额外排查点
- 抓包对比真实请求:用Charles、Fiddler等工具抓取APP的原始请求,逐字段对比请求头、方法、请求体的细节(包括大小写、空格)。
- 检查认证信息:确认是否遗漏APP请求中的Cookie、Authorization Token等认证字段。
- 校验请求签名:部分APP会生成签名参数(如
sign),需按照APP的签名算法生成对应值,这是403的常见原因。
内容的提问来源于stack exchange,提问作者user18686221
相关产品推荐
相关产品推荐

