Python用aiohttp登录网站失败但requests正常的问题排查
问题描述
使用requests同步登录目标网站(https://hac.friscoisd.org)完全正常,但切换为aiohttp异步实现后,POST请求始终无法跳转到受保护页面,停留在登录页。排查发现:aiohttp请求的Cookie中缺少.AuthCookie,而requests请求中该Cookie正常存在,推测是第一次GET请求时aiohttp未正确保存该Cookie。
附aiohttp实现代码:
async def asyncGetRequestSession(self, username, password): try: async with aiohttp.ClientSession() as requestSession: async with requestSession.get( "https://hac.friscoisd.org/HomeAccess/Account/LogOn?ReturnUrl=%2fHomeAccess%2f") as loginScreenResponse: loginScreenResponseText = await loginScreenResponse.text() parser = BeautifulSoup(loginScreenResponseText, "lxml") # 从登录页获取验证令牌 requestVerificationToken = parser.find('input', attrs={'name': '__RequestVerificationToken'})["value"] # POST请求头 requestHeaders = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) ' 'Chrome/36.0.1985.125 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', 'Host': 'hac.friscoisd.org', 'Origin': 'hac.friscoisd.org', 'Referer': "https://hac.friscoisd.org/HomeAccess/Account/LogOn?ReturnUrl=%2fhomeaccess%2f", '__RequestVerificationToken': requestVerificationToken } # POST请求参数 requestPayload = { "__RequestVerificationToken": requestVerificationToken, "SCKTY00328510CustomEnabled": "False", "SCKTY00436568CustomEnabled": "False", "Database": "10", "VerificationOption": "UsernamePassword", "LogOnDetails.UserName": username, "tempUN": "", "tempPW": "", "LogOnDetails.Password": password } async with requestSession.post( "https://hac.friscoisd.org/HomeAccess/Account/LogOn?ReturnUrl=%2fHomeAccess%2f", data=requestPayload, headers=requestHeaders, ) as pageDOM: print(pageDOM.url) # 登录失败,返回原始登录页URL if pageDOM.url == "https://hac.friscoisd.org/HomeAccess/Account/LogOn?ReturnUrl=%2FHomeAccess%2F": return HTTPException(status_code=400, detail="HAC Login Failed") return requestSession except: raise HTTPException(status_code=500, detail="HAC Server Error")
排查方向与解决建议
1. 确认GET请求的Cookie接收情况
aiohttp的ClientSession默认自动处理Cookie,但可能因Cookie属性(如HttpOnly、Secure)导致保存异常。在GET请求后打印响应Cookie,确认.AuthCookie是否被正确返回:
async with requestSession.get(url) as resp: print(resp.cookies) # 打印所有返回的Cookie loginScreenResponseText = await resp.text()
如果.AuthCookie在resp.cookies中存在但后续POST未携带,说明Session的CookieJar配置有问题。
2. 调整CookieJar安全策略
默认CookieJar的严格安全策略可能拦截部分Cookie,尝试使用宽松模式:
from aiohttp import CookieJar # 创建宽松模式CookieJar,关闭部分安全校验 cookie_jar = CookieJar(unsafe=True) async with aiohttp.ClientSession(cookie_jar=cookie_jar) as requestSession: # 原有请求逻辑不变
注:unsafe=True仅用于调试,生产环境需谨慎使用。
3. 简化请求头,避免手动覆盖自动生成的字段
aiohttp会自动生成Host、Origin等标准头,手动设置可能导致格式或大小写错误(比如Referer中的homeaccess与实际URL的HomeAccess大小写不一致)。建议只保留必要自定义头:
requestHeaders = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36', 'X-Requested-With': 'XMLHttpRequest', 'Referer': "https://hac.friscoisd.org/HomeAccess/Account/LogOn?ReturnUrl=%2fHomeAccess%2f", # 修正大小写与URL一致 }
4. 手动处理重定向,验证Cookie携带情况
aiohttp默认跟随重定向,但重定向过程中可能丢失Cookie。关闭自动重定向,手动处理:
async with requestSession.post(url, data=requestPayload, headers=requestHeaders, allow_redirects=False) as pageDOM: print(pageDOM.status) print(pageDOM.headers.get('Location')) # 查看重定向目标 # 手动发起重定向请求,确保Cookie携带 if pageDOM.status in (301, 302): async with requestSession.get(pageDOM.headers.get('Location')) as resp: print(resp.url)
5. 对比requests与aiohttp的请求细节
用抓包工具(如Charles、Fiddler)捕获两种方式的请求,对比以下内容:
- GET请求的响应Cookie属性(
Domain、Path等) - POST请求的请求头(Cookie、Referer、Origin的大小写和格式)
- POST请求的表单参数(编码、顺序是否完全一致)
服务器可能对请求细节敏感,细微差异都会导致登录失败。
内容的提问来源于stack exchange,提问作者danielrhabib
相关产品推荐
相关产品推荐

