如何基于响应头用requests爬取网站?解决API授权无效问题
问题分析与解决方案
一、响应头中需关注的关键信息
- Set-Cookie:接口返回的
advanced-api是HttpOnly类型的会话Cookie,后续请求大概率需要携带它,很多站点会把会话凭证和Cookie绑定,缺失可能触发授权验证失败。 - 缓存控制头(Cache-Control/Expires/Pragma):这些字段强制禁用缓存,确保每次请求都获取最新数据,避免使用过期的旧凭证导致错误。
- Access-Control-Allow-Origin:虽然这是浏览器端的跨域限制,爬虫中影响不大,但要保证请求的
Origin头和浏览器发起的一致,部分站点会校验这个字段。
二、解决"invalid Authorization"错误的核心操作
你硬编码的Bearer Token是临时凭证,这类Token通常和会话绑定、有有效期,必须从合法渠道获取:
- 抓取浏览器中的有效Token
打开目标页面后按F12调出开发者工具,切换到「Network」标签刷新页面,找到productbycategoryv2的请求,在「Request Headers」里复制真实的Authorization值,替换代码里的旧Token。 - 携带会话Cookie
响应头里的advanced-apiCookie是会话标识,建议用requests的Session对象自动管理Cookie,或者手动把Cookie添加到请求头中。 - 修正请求格式不匹配问题
你的代码用json=payload发送请求,但headers里设置的是Content-Type: application/x-www-form-urlencoded,这会导致请求格式冲突。要么改用data=payload发送表单数据,要么把Content-Type改成application/json。
三、修正后的示例代码
import requests payload = { 'store': '49', 'category_id': '', 'search': '', 'filter': '', 'tag': '', 'lang': 'ID', 'page': '0' } # 用Session自动管理会话Cookie session = requests.Session() # 先访问目标页面初始化会话 session.get('https://www.foodhall.co.id/grand-indonesia/catalog') headers = { # 替换成从浏览器抓取的有效Authorization Token 'Authorization': 'Bearer YOUR_VALID_TOKEN_HERE', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36', 'Origin': 'https://www.foodhall.co.id', 'Referer': 'https://www.foodhall.co.id/grand-indonesia/catalog' } # 这里假设接口接受表单格式数据,若实际是JSON则改用json=payload response = session.post( 'https://api.foodhall.co.id/v1/catalog/productbycategoryv2', data=payload, headers=headers ) print(response.json())
额外提醒
- Token有有效期,需要定期重新抓取,若站点需要登录才能获取数据,还得模拟登录流程自动生成有效Token。
- 控制请求频率,避免触发站点的反爬机制导致IP被封禁。
- 确保请求的所有参数(如store、page)和浏览器发起的请求完全一致。
内容的提问来源于stack exchange,提问作者Hal
相关产品推荐
相关产品推荐

