Aiohttp携带Cookie请求YouTube接口返回未登录但Requests正常,如何解决?
修复方案
1. 移除async with session:上下文管理器
你在外部已经初始化了公共的aiohttp.ClientSession实例,在login函数内部使用async with session:会在函数执行完毕后自动关闭该会话,导致会话内存储的动态Cookie、连接状态全部丢失,同步代码没有这步逻辑,这是最明显的差异点。
修改后的login函数结构:
async def login(session): headers = {'accept-encoding': 'gzip, deflate, br' ...} # 移除async with session包裹逻辑 async with session.get('https://www.youtube.com', headers= headers) as response: yt = await response.text() # 保留生成google专属头和payload的原有逻辑 # 和同步代码对齐,把生成的额外鉴权头(比如SAPISIDHASH、X-Goog-AuthUser等)合并到POST请求头 post_headers = headers.copy() post_headers.update(addit_headers) async with session.post('https://www.youtube.com/youtubei/v1/guide', headers= post_headers,\ params= {'key': innertube_key}, json = guide_payload) as response: tmp = await response.json()
2. 正确配置CookieJar匹配Requests的Cookie逻辑
aiohttp默认的CookieJar采用严格的同源、域名匹配规则,如果你传入的mycookies是普通键值对字典,会默认绑定到首次请求的完整域名,不会自动应用到所有youtube.com的子域/根域请求,导致POST到youtubei/v1接口时未携带Cookie。
修改会话初始化逻辑,显式配置适配根域Cookie的CookieJar:
from aiohttp import CookieJar async def set_up_session(mycookies): # 配置CookieJar关闭严格域名校验、不对Cookie值做额外转义,和Requests行为对齐 jar = CookieJar(unsafe=True, quote_cookie=False) # 手动逐个设置Cookie,和同步代码的session.cookies.set逻辑对齐 # 如果mycookies是普通键值对字典,统一指定根域即可 for k, v in mycookies.items(): jar.set(k, v, domain='.youtube.com', path='/') # 如果mycookies是带domain、path等元数据的对象列表,改用下面的逻辑 # for cookie_kwargs in mycookies: # jar.update_cookies(**cookie_kwargs) return aiohttp.ClientSession(cookie_jar=jar)
3. 调整重定向处理逻辑匹配Requests行为
aiohttp默认对POST请求的3xx重定向会自动将请求方法改为GET,同时丢弃请求体和部分鉴权头,和Requests默认保留原方法的逻辑不同,可以在POST请求中显式指定allow_redirects=False手动处理重定向,避免鉴权信息丢失:
async with session.post( 'https://www.youtube.com/youtubei/v1/guide', headers= post_headers, params= {'key': innertube_key}, json = guide_payload, allow_redirects=False ) as response: tmp = await response.json()
验证步骤
修改完成后可以在POST请求前打印session.cookie_jar的所有Cookie,确认携带的Cookie和同步代码执行到POST时的Cookie完全一致,同时检查请求头是否和同步代码的addit_headers完全匹配,即可解决未登录报错。
内容的提问来源于stack exchange,提问作者asker956859035
相关产品推荐
相关产品推荐

