Postman请求正常但Python代码返回403错误的解决办法
使用Python调用Williams-Sonoma API返回403 Restricted Access错误的解决方案
问题描述
我编写了一段用http.client调用Williams-Sonoma API的Python代码:
import http.client conn = http.client.HTTPSConnection("www.williams-sonoma.com") payload = '' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Cookie': '<some value here>'} conn.request("GET", "/api/catalog/v1/catalogobjects/query/?skuId=8739781", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
在Postman中发送完全相同的请求能获取正常的商品JSON响应:
[{"id":"glass-prep-bowl-8-piece-set","imageUrl":"https://assets.wsimgs.com/wsimgs/rk/images/dp/wcm/202340/0374/img40t.jpg","name":"Glass Prep Mixing Bowls, Set of 8","salePriceMax":34.95,"salePriceMin":34.95,"regularPriceMax":24.95,"regularPriceMin":24.95,"skuId":"8739781","available":true,"sellable":true}]
但Python代码执行后返回403 Restricted Access错误页面:
<!DOCTYPE html> <html> <head> <title>Williams-Sonoma: 403 - Restricted Access</title> <meta charset="utf-8" /> <link rel="stylesheet" href="/netstorage/css/common.css" type="text/css" media="all" /> <link rel="stylesheet" href="/netstorage/css/errors.css" type="text/css" media="all" /> </head> <body> <div class="error-container"> <img src="/netstorage/images/logo-ws.png" alt="Williams-Sonoma" /> <p>Sorry, due to website restrictions we are unable to display the requested page.</p> </div> <!-- Analytics --> <script type="text/javascript"> window.digitalData = { page: { pageName: "Restricted Access Error", attributes: { cmPageId : "Restricted Access Error", cmCategoryId : "ERROR" }, pageCategory: { primaryCategory: "error" } } }; var utag_data = {}; (function(a,b,c,d){ a='//tags.tiqcdn.com/utag/wsi/williamssonoma/prod/utag.js'; b=document;c='script';d=b.createElement(c); d.src=a; d.type='text/java'+c; d.async=true; a=b.getElementsByTagName(c)[0]; a.parentNode.insertBefore(d,a); })(); </script> <!-- end Analytics --> </body> </html>
问题原因
服务器返回403通常是因为请求缺少必要的验证信息:Postman会自动添加浏览器默认的请求头,而你的Python代码只指定了User-Agent和Cookie,缺少Accept、Referer等关键头信息;另外Cookie值可能不完整或无效。
解决办法
1. 完整复制Postman的请求头
将Postman中请求的所有头信息复制到Python代码中,确保请求头和Postman完全一致。修改后的http.client代码如下:
import http.client conn = http.client.HTTPSConnection("www.williams-sonoma.com") payload = '' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Cookie': '替换为Postman中完整的Cookie值', 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'en-US,en;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://www.williams-sonoma.com/', 'Connection': 'keep-alive' } conn.request("GET", "/api/catalog/v1/catalogobjects/query/?skuId=8739781", payload, headers) res = conn.getresponse() data = res.read() print(data.decode("utf-8"))
2. 使用requests库简化请求(推荐)
requests库更易用,能自动处理很多底层细节,模拟浏览器请求更准确。示例代码:
import requests url = "https://www.williams-sonoma.com/api/catalog/v1/catalogobjects/query/?skuId=8739781" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36', 'Cookie': '替换为Postman中完整的Cookie值', 'Accept': 'application/json, text/plain, */*', 'Accept-Language': 'en-US,en;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Referer': 'https://www.williams-sonoma.com/', 'Connection': 'keep-alive' } response = requests.get(url, headers=headers) print(response.json())
注意事项
- 确保
Cookie值是从Postman的请求头中完整复制的,不要遗漏任何键值对,Cookie中的会话标识或CSRF令牌是服务器验证的关键。 - 如果后续再次出现403,可能是Cookie过期,需要重新从Postman中获取最新的Cookie值。
内容的提问来源于stack exchange,提问作者Ashish Khatana
相关产品推荐
相关产品推荐

