You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Python请求登录Spotify返回errorUnknown错误求助

Spotify程序化登录返回400 errorUnknown问题排查

我尝试用Python结合Playwright和ReCaptcha V3绕过方案(go-recaptcha-v3-bypass或2Captcha)实现Spotify的程序化登录。流程是通过Playwright提取有效的flow_ctx和Cookie,完成ReCaptcha验证后用requests.post发起登录请求。

尽管提供了所有看似有效的数据——正确的请求头、Cookie、CSRF Token、recaptchaToken和flow_ctx,Spotify始终返回400 Bad Request,响应内容为{"error":"errorUnknown"}。用相同账号密码在浏览器手动登录完全正常,只有用requests调用时出现这个错误。

以下是我的代码:

import requests
from urllib.parse import quote
from playwright.sync_api import sync_playwright
from pypasser import reCaptchaV3

EMAIL = ""
PASSWORD = ""
UA = "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Mobile Safari/537.36"

def get_anchor_flowctx_and_cookies():
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context(user_agent=UA)
        page = context.new_page()
        page.goto("https://accounts.spotify.com/en/login", wait_until="networkidle")

        anchor_url = ""
        for frame in page.frames:
            if "recaptcha/enterprise/anchor" in frame.url:
                anchor_url = frame.url
                break
        if not anchor_url:
            raise RuntimeError("Anchor URL not found")

        flowctx = page.eval_on_selector("meta#bootstrap-data", """el => {
            try {
                const raw = el.getAttribute("sp-bootstrap-data").replace(/"/g, '"');
                const parsed = JSON.parse(raw);
                return parsed.flowCtx;
            } catch (e) {
                return null;
            }
        }""")
        if not flowctx:
            raise RuntimeError("flowCtx not found")

        # 获取上下文Cookie
        cookies = context.cookies()
        cookie_dict = {cookie["name"]: cookie["value"] for cookie in cookies if ".spotify.com" in cookie["domain"]}

        browser.close()
        return anchor_url, flowctx, cookie_dict

def bypass_recaptcha(anchor_url: str) -> str:
    return reCaptchaV3(anchor_url)

def spotify_login(email, password, token, flow_ctx, cookie_dict):
    session = requests.Session()

    for name, value in cookie_dict.items():
        session.cookies.set(name, value, domain=".spotify.com")

    session.cookies.set("remember", email, domain=".spotify.com")
    print(session.cookies)
    csrf = cookie_dict.get("sp_sso_csrf_token")
    if not csrf:
        raise RuntimeError("CSRF token not found")

    data = {
        "username": email,
        "password": password,
        "continue": f"https%3A%2F%2Fopen.spotify.com%2F%3Fflow_ctx%3D{flow_ctx}",
        "recaptchaToken": token,
        "flow_ctx": flow_ctx,
    }
    headers = {
        "User-Agent": UA,
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Csrf-Token": csrf,
        "Origin": "https://accounts.spotify.com",
        "Referer": f"https://accounts.spotify.com/en/login?flow_ctx={quote(flow_ctx)}",
    }

    resp = session.post("https://accounts.spotify.com/login/password", data=data, headers=headers)
    return resp.text, resp.status_code

if __name__ == "__main__":
    anchor_url, flow_ctx, cookie_dict = get_anchor_flowctx_and_cookies()
    print("✅ anchor:", anchor_url)
    print("✅ flowCtx:", flow_ctx)

    token = bypass_recaptcha(anchor_url)
    print("✅ recaptchaToken:", token)

    result, code = spotify_login(EMAIL, PASSWORD, token, flow_ctx, cookie_dict)
    print(result)
    print(code)

可能的问题及修复方案

1. Cookie传递不完整

你过滤了仅包含.spotify.com的Cookie,但浏览器登录时accounts.spotify.com域下的Cookie同样关键。修改Cookie获取逻辑,保留所有Cookie并按原始域传递:

# 替换原Cookie处理逻辑
cookies = context.cookies()
cookie_dict = {cookie["name"]: cookie["value"] for cookie in cookies}

# 设置Cookie时保留原始域和路径
for cookie in cookies:
    session.cookies.set(
        cookie["name"], 
        cookie["value"], 
        domain=cookie.get("domain"), 
        path=cookie.get("path")
    )

2. ReCaptcha Token有效性不足

pypasser对Enterprise版ReCaptcha的支持有限,Spotify用的是ReCaptcha Enterprise,建议换成专业的验证码服务(如2Captcha)生成针对性Token,确保Token绑定当前登录会话的上下文。

3. 请求头缺失关键字段

浏览器登录时会携带更多标识字段,补充后模拟更真实的请求:

headers = {
    "User-Agent": UA,
    "Content-Type": "application/x-www-form-urlencoded",
    "X-Csrf-Token": csrf,
    "Origin": "https://accounts.spotify.com",
    "Referer": f"https://accounts.spotify.com/en/login?flow_ctx={quote(flow_ctx)}",
    "Accept": "application/json, text/plain, */*",
    "Accept-Language": "en-US,en;q=0.9",
    "Sec-Fetch-Dest": "empty",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Site": "same-origin"
}

4. Flow Context时效性

flow_ctx有有效期,缩短从获取到发起登录请求的间隔,避免失效。或者在获取ReCaptcha Token后,重新从页面提取一次flow_ctx。

5. 直接用Playwright完成登录

既然Playwright已经能加载登录页面,直接用它完成输入、验证和登录操作,避免requests与Playwright的上下文不一致:

def playwright_spotify_login(email, password):
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=False)
        context = browser.new_context(user_agent=UA)
        page = context.new_page()
        page.goto("https://accounts.spotify.com/en/login", wait_until="networkidle")
        
        # 输入账号密码
        page.fill('input[name="username"]', email)
        page.fill('input[name="password"]', password)
        
        # 等待ReCaptcha验证完成(可集成2Captcha自动处理)
        # 点击登录按钮
        page.click('button[data-testid="login-button"]')
        
        # 等待跳转至主页
        page.wait_for_url("https://open.spotify.com/", wait_until="networkidle")
        
        # 获取登录后的Cookie
        cookies = context.cookies()
        browser.close()
        return cookies

内容的提问来源于stack exchange,提问作者Cevin Soprano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 00:23:16