使用Python请求登录Spotify返回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

