请求返回200 OK但仍重定向至登录页,用户名密码字段为空求助
Python模拟登录返回200但仍重定向至登录页的问题排查与解决
你遇到的问题是:使用requests和BeautifulSoup模拟登录时,请求返回200 OK状态码,但页面仍重定向到登录页,且用户名密码字段为空,已确认账号密码正确。以下是具体的排查点和修复方案:
核心问题排查与修复
1. 协议不一致导致会话失效
你的代码中,GET请求使用HTTPS(https://xxxxxxxxxx.com),但POST登录请求使用HTTP(http://xxxxxxxxxx.com/login)。跨协议请求会导致会话Cookie无法共享,服务器无法识别你的会话,直接重定向回登录页。
修复:统一使用HTTPS发送POST请求,确保域名和协议完全一致。
2. 请求头缺失关键字段
仅设置User-Agent可能不够,很多站点会校验Referer字段(验证请求来源),缺少该字段可能被判定为非法请求。
修复:在请求头中添加Referer,值为登录页面的URL。
3. CSRF Token获取方式可能错误
部分站点的CSRF Token会放在表单的隐藏输入框中,而非meta标签。如果从meta标签获取的Token无效,服务器会拒绝登录请求。
修复:优先从表单的隐藏字段中提取authenticity_token,再 fallback到meta标签。
4. 自动重定向掩盖真实响应状态
requests默认自动跟随重定向,返回的200可能是重定向后的登录页状态码,而非登录成功的响应。关闭自动重定向可以查看真实的登录响应状态。
修复:POST请求时添加allow_redirects=False,查看响应状态码和Location头,确认是否登录成功。
修改后的代码示例
import requests from bs4 import BeautifulSoup header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edg/118.0.2088.61', 'Referer': 'https://xxxxxxxxxx.com/login' # 添加Referer头 } Payload = { "utf8": "✓", "spree_user[email]": "yavixe4893@tutoreve.com", "spree_user[password]": "Qwerty@123", "spree_user[remember_me]": "0", "commit": "Login", } with requests.Session() as ses: # 先访问登录页面,获取CSRF token和会话Cookie login_url = "https://xxxxxxxxxx.com/login" req = ses.get(login_url, headers=header) soup = BeautifulSoup(req.content, 'html5lib') # 优先从表单隐藏字段获取authenticity_token token_input = soup.find('input', {'name': 'authenticity_token'}) if token_input: Payload['authenticity_token'] = token_input['value'] else: # fallback到meta标签 meta_token = soup.find('meta', {'name': 'csrf-token'}) if meta_token: Payload['authenticity_token'] = meta_token['content'] # 统一用HTTPS发送POST请求,关闭自动重定向查看真实响应 res = ses.post(login_url, data=Payload, headers=header, allow_redirects=False) print(f"响应状态码: {res.status_code}") print(f"重定向地址: {res.headers.get('Location')}") print(res.content)
额外排查建议
- 用浏览器开发者工具(F12)抓包,对比浏览器发送的登录请求和代码请求的请求头、表单字段、Cookie,确保所有参数完全匹配。
- 检查响应的
Set-Cookie头,确认会话Cookie是否被正确设置,后续请求是否携带这些Cookie。 - 如果浏览器中提交的密码是加密后的字符串,说明站点存在JS加密逻辑,需要分析加密算法,将明文密码加密后再发送。
内容的提问来源于stack exchange,提问作者Abdul Khadar
相关产品推荐
相关产品推荐

