使用Python登录带csrfmiddlewaretoken验证的网站遇索引错误求助
问题原因及解决办法
报错原因
你遇到的IndexError: list index out of range,本质是HTML.find_all('input')返回的列表里没有索引为1的元素——要么页面里的<input>标签数量不足2个,要么请求没拿到正确的登录页面,导致解析后找不到任何<input>标签。
具体可能的情况:
- 页面结构和预期不符:你默认第二个
<input>是CSRF令牌,但实际网站的CSRF令牌可能是第一个<input>,或者页面里根本没这么多input标签。 - 请求失败,未获取正常页面:比如网站反爬拦截了你的请求,返回空白页、404/500错误页,此时解析内容里没有表单相关的
<input>标签,find_all('input')会返回空列表。 - 定位CSRF令牌的方式太脆弱:用固定索引取元素完全依赖页面结构不变,一旦网站更新布局,代码直接失效。
解决步骤
1. 先确认请求是否成功
在get_url = session.get(...)后加一行代码,检查请求状态码:
print(get_url.status_code)
如果输出不是200,说明请求被拦截或地址有误,需要添加浏览器头模拟正常访问,示例:
headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } get_url = session.get('https://text.gob.pe/accounts/login/', headers=headers)
2. 正确定位CSRF令牌
不要用固定索引,通过name属性精准查找CSRF令牌的<input>标签,这是更可靠的方式:
csrf_input = HTML.find('input', {'name': 'csrfmiddlewaretoken'}) if not csrf_input: print("找不到CSRF令牌标签") exit() csrfmiddlewaretoken = csrf_input['value']
3. 修正payload里的错误
你的payload里重复了next键,且路径包含多余空格,修改后:
payload = { 'next': '/profile/', 'username': 'secret', 'password': 'secret', 'csrfmiddlewaretoken': csrfmiddlewaretoken }
修正后的完整代码
import requests from bs4 import BeautifulSoup request_url = 'https://text.gob.pe/accounts/login/' with requests.session() as session: # 加User-Agent模拟浏览器 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' } get_url = session.get(request_url, headers=headers) # 检查请求状态 if get_url.status_code != 200: print(f"请求失败,状态码:{get_url.status_code}") exit() HTML = BeautifulSoup(get_url.text, 'html.parser') # 精准查找CSRF令牌 csrf_input = HTML.find('input', {'name': 'csrfmiddlewaretoken'}) if not csrf_input: print("页面中未找到CSRF令牌") exit() csrfmiddlewaretoken = csrf_input['value'] # 登录参数 payload = { 'next': '/profile/', 'username': 'secret', 'password': 'secret', 'csrfmiddlewaretoken': csrfmiddlewaretoken } # 登录请求的headers加上Referer login_headers = { 'Referer': request_url, 'User-Agent': headers['User-Agent'] } login_request = session.post(request_url, data=payload, headers=login_headers) home_page = session.get("https://text.gob.pe/ficha/buscar/") print(home_page.content)
内容的提问来源于stack exchange,提问作者AjaxPain
相关产品推荐
相关产品推荐

