Playwright登录会话Cookie迁移至Python requests调用受保护API返回403 Forbidden问题求助
我之前也碰到过一模一样的糟心事——明明Playwright登录成功了,把Cookie移去requests就直接403,折腾了好久才找到几个关键的排查方向,你可以挨个试试:
1. 不要只传递Cookie的name/value,要完整导入Cookie属性
浏览器里的Cookie不止有名称和值,还有Domain、Path、SameSite这些关键属性,requests直接传字典的话会丢失这些信息,服务器很可能因此不认你的会话。试试用requests.utils.add_dict_to_cookiejar把Playwright的完整Cookie对象导入到requests会话里:
import requests from requests.utils import add_dict_to_cookiejar # Playwright登录后获取完整Cookie列表(不是只取name:value) playwright_cookies = context.cookies() # 创建requests会话并导入Cookie session = requests.Session() for cookie in playwright_cookies: add_dict_to_cookiejar(session.cookies, cookie) # 发起请求时不用再手动传cookies参数 response = session.get( "https://example.com/api/data", headers={ "accept": "application/json", "csrf-token": session.cookies.get("CSRF_COOKIE", ""), "user-agent": page.evaluate("navigator.userAgent"), # 直接用Playwright的UA,避免不一致 "referer": "https://example.com/" # 很多网站会校验Referer头 } )
2. 确认CSRF Token的来源是否正确
你现在是直接取Cookie里的CSRF_COOKIE当请求头,但很多网站的CSRF Token其实是存在页面的meta标签或者JS全局变量里的,不是Cookie值。比如:
# 登录后从页面meta标签提取CSRF Token csrf_token = page.locator('meta[name="csrf-token"]').get_attribute('content') # 或者如果是存在window对象里的情况 csrf_token = page.evaluate("window.csrfToken") # 再把这个值放到请求头里 HEADERS["csrf-token"] = csrf_token
3. 严格对齐请求头的所有细节
服务器可能会校验请求头的细微差异,比如:
- User-Agent: 直接用Playwright页面的UA,不要手动写(毕竟手动写的可能和浏览器实际发送的有差别)
- Referer: 必须是网站的首页或当前页面地址,很多API会拒绝无Referer的请求
- 其他自定义头: 打开浏览器F12的Network面板,找到登录后正常请求API的请求头,把所有非默认的头都加到requests里
4. 检查Cookie值的格式问题
你写了清理引号的函数,但还要注意:
- 有些Cookie值是URL编码的,Playwright返回的是解码后的,而requests可能需要编码后的?可以试试用
urllib.parse.quote处理值 - 不要随意修改Cookie值,先直接用Playwright返回的原始值测试,排除格式问题
5. 对比浏览器和requests的请求差异
最有效的排查方法是:
- 在浏览器里登录后,打开Network面板,找到正常调用API的请求,右键「复制为cURL」
- 把cURL转换成Python requests代码(可以用在线工具或者手动转)
- 对比你自己的代码,看哪里缺少了头信息、Cookie属性或者参数
内容的提问来源于stack exchange,提问作者P K




