Python requests.post()本地正常但Windows Server返回403问题排查
问题描述
使用Python requests库向API发送POST请求时,本地Windows机器运行代码正常,但部署到Windows Server 2022环境后始终返回HTTP 403状态码。
代码示例
import requests url = "https://example.com/api/test" payload = { "name": "test" } headers = { "User-Agent": "Mozilla/5.0" } response = requests.post(url, json=payload, headers=headers) print(response.status_code) print(response.text)
环境信息
- Python 3.11
- Windows Server 2022
- requests 2.32.0
已排查项
- 防火墙已禁用
- SSL证书已更新
- 代理配置与本地机器一致
可能的原因及排查方向
- 服务器IP被API服务商限制:多数API会对数据中心/云服务器IP做拦截,这类IP常被标记为批量访问风险源。可以在服务器上用curl或者浏览器(有桌面环境的话)发送相同请求,或者换个代理IP测试,验证是否是IP层面的限制。
- 请求头字段不完整:仅设置User-Agent可能不够,有些API会校验
Accept、Accept-Language、Referer等浏览器默认带的字段。本地浏览器的请求头更全,服务器环境的requests请求因缺失字段被拦截。可以抓本地浏览器的请求头(F12网络面板),全部复制到代码的headers里测试。 - Windows Server安全策略拦截:Windows Server 2022自带的Windows Defender应用控制、组策略可能限制了Python程序的网络请求,导致请求被篡改或阻断。可以临时关闭Windows Defender实时保护,或者检查组策略中的网络访问规则。
- SSL/TLS配置差异:虽然requests版本相同,但Windows Server的系统底层SSL配置可能和本地不同,比如默认加密套件不被API服务器兼容。可以尝试指定TLS版本和加密套件:
import requests from requests.adapters import HTTPAdapter from urllib3.poolmanager import PoolManager import ssl class TLSAdapter(HTTPAdapter): def init_poolmanager(self, *args, **kwargs): ctx = ssl.create_default_context() ctx.set_ciphers('DEFAULT@SECLEVEL=1') ctx.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 kwargs['ssl_context'] = ctx return super().init_poolmanager(*args, **kwargs) session = requests.Session() session.mount('https://', TLSAdapter()) response = session.post(url, json=payload, headers=headers) - API地域访问限制:如果API服务商限制了访问地域,本地机器所在地区允许,但Windows Server所在地区被禁止,也会返回403。可以查询服务器公网IP的地域,对比本地IP,或者用对应地域的代理测试。
- 请求内容编码差异:Windows Server的系统编码可能和本地不同,虽然用了
json=payload,但实际发送的JSON可能存在编码细微差异,被API拒绝。可以手动序列化JSON后发送:import json headers["Content-Type"] = "application/json" response = requests.post(url, data=json.dumps(payload), headers=headers)
内容的提问来源于stack exchange,提问作者Husky
相关产品推荐
相关产品推荐

