You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将Playwright登录会话Cookie正确迁移至Python requests库以通过受保护API身份验证?

我之前也踩过Playwright转requests会话的403坑,结合你的描述,几个容易漏掉的细节大概率是问题所在,咱们一步步来排查解决:

可能的问题点与对应解决方案

1. 忽略了Cookie的Domain/Path等关键属性

你已经处理了Cookie值的引号问题,这点做得很好,但可能忽略了Cookie的Domain、Path、Secure这些属性——很多服务器会严格校验这些属性是否匹配请求的URL。直接用字典传递Cookie会丢失这些信息,建议转换成RequestsCookieJar来完整保留:

from requests.cookies import RequestsCookieJar
import json

def clean(v):
    v = v.strip()
    if v.startswith('"') and v.endswith('"'):
        try:
            return json.loads(v)
        except Exception:
            return v.strip('"')
    return v

jar = RequestsCookieJar()
for cookie in context.cookies():
    clean_val = clean(cookie["value"])
    jar.set(
        cookie["name"],
        clean_val,
        domain=cookie["domain"],
        path=cookie["path"],
        secure=cookie["secure"],
        httponly=cookie["httponly"]
    )

# 发起请求时使用这个CookieJar
response = requests.get(
    "https://example.com/api/data",
    headers=HEADERS,
    cookies=jar
)

2. 请求头缺失浏览器环境的关键字段

浏览器发送请求时会携带很多额外的头信息(比如RefererOriginsec-*系列字段),服务器可能会通过这些字段判断请求是否来自合法的浏览器环境。你可以在Playwright里抓一下登录后正常请求API的完整头,然后把这些字段补到requests的HEADERS里:

# 参考Playwright捕获的请求头,补全缺失字段
HEADERS = {
    "accept": "application/json",
    "csrf-token": COOKIES.get("CSRF_COOKIE", ""),
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/124.0.0.0 Safari/537.36",
    "referer": "https://example.com/",  # 登录后的首页地址
    "origin": "https://example.com",    # 网站的根域名
    "sec-ch-ua": "\"Chromium\";v=\"124\", \"Google Chrome\";v=\"124\", \"Not-A.Brand\";v=\"99\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\"",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin"
}

3. CSRF Token的获取方式不正确

有些网站的CSRF Token并不是存放在Cookie里,而是放在页面的meta标签中(比如<meta name="csrf-token" content="xxx">)。你可以检查Playwright登录后的页面,确认Token的来源:

# 尝试从页面meta标签提取CSRF Token
csrf_token = page.locator('meta[name="csrf-token"]').get_attribute('content')
# 优先使用meta标签的Token, fallback到Cookie值
HEADERS["csrf-token"] = csrf_token or COOKIES.get("CSRF_COOKIE", "")

4. 服务器绑定了浏览器指纹

如果上面的方法都没用,可能是服务器做了浏览器指纹校验——Playwright的浏览器环境和requests的纯HTTP请求环境差异很大,服务器可能识别出不是同一个客户端。这种情况可以试试两个方向:

  • 让Playwright使用更贴近真实浏览器的配置(比如启用launch_persistent_context保留会话,关闭自动化特征)
  • 直接用Playwright发起API请求,跳过requests的转换:
# 用Playwright的context直接发送API请求,复用登录后的会话
api_response = context.request.get(
    "https://example.com/api/data",
    headers=HEADERS
)
print(api_response.status)
print(api_response.json())

建议先尝试前两个方案,这是最常见的403原因。如果还是不行,再逐步排查后面的可能性。

内容的提问来源于stack exchange,提问作者P K

火山引擎 最新活动