[Python] Why does Spotify return {"error":"errorUnknown"} when submitting login credentials...

Discussão em 'Python' iniciado por Stack, Junho 1, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to programmatically log into Spotify using Python, with the help of Playwright and a ReCaptcha V3 bypass solution (go-recaptcha-v3-bypass or 2Captcha). I extract the correct flow_ctx and cookies via Playwright, solve the ReCaptcha, and then attempt to log in using requests.post.

    Despite providing what appears to be all valid data — correct headers, cookies, CSRF token, recaptchaToken, and flow_ctx — Spotify responds with a 400 Bad Request and this JSON:

    {"error":"errorUnknown"}

    This doesn't happen in the browser with the exact same credentials. It only happens with requests.

    Here's my code:

    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")

    # Забираем куки из контекста
    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)

    Continue reading...

Compartilhe esta Página