我正在尝试用dart写一个软件,希望通过模拟登录的方式获取到cookie,然后用cookie获取学校教务系统的信息,流程大概是:
- 访问CAS页面,获取一个初始的JSESSIONID值
- POST请求,携带一些信息和刚才获取到的JSESSION ID,如果成功会给几个cookie(如_pc0)等
- 用这些cookie去请求学校办事大厅页面,即可获取到一个key,用这个key即可请求到课表等信息。
最开始使用python可以完全实现这个功能,
但是换成dart会卡死在第三步:明明第二步已经成功获取到cookie,但是第三步请求办事大厅会跳转到登录页面(可能是后台不认为这是一个会话)
尝试用java也不行,发现只有python的request可以正常实现
这是python的代码:
import requests
import json
# 创建一个session对象
session = requests.Session()
login_url = '登录地址'
page_url = '个人中心地址'
# 从登录页面获取一个跟踪元素
response = session.get(login_url)
from bs4 import BeautifulSoup
soup = BeautifulSoup(response.text, 'html.parser')
tracking_element = soup.find('input', {'name': 'execution'}).get('value')
print(tracking_element)
# 构造登录数据
login_data = {
'username': '学号',
'password': '密码',
'authcode': '',
'rememberMe': 'true',
'execution': tracking_element, # 添加跟踪元素到登录数据中
'_eventId' : 'submit'
}
# 发送POST请求进行登录
response = session.post(login_url, data=login_data)
# 登录后访问页面
response = session.get(page_url)
cookies = response.cookies
print(response.text)
# 打印页面内容
# print(response.text)
print(cookies)
with open('cookies.txt', 'w') as f:
json.dump(requests.utils.dict_from_cookiejar(session.cookies), f)
这个代码没有任何问题,可以成功获取到key。
但是换成用flutter/java就不行
final loginResponse = await dio.post(
loginUrl,
options: Options(
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
followRedirects: false, // 禁用自动重定向
validateStatus: (status) => status != null && status < 500,
),
data: {
'username': username,
'password': password,
'authcode': '', // 如果有验证码,可以在此添加
'execution': executionToken,
'_eventId': 'submit',
},
);
// 检查是否返回 302 状态码 (重定向)
if (loginResponse.statusCode == 302) {
// 获取登录后的 cookies
final cookieJar = dio.interceptors.whereType<CookieManager>().single.cookieJar;
final cookies = await cookieJar.loadForRequest(Uri.parse(loginUrl));
final cookieHeader = cookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
print(cookieHeader);
// 登录成功后保存 cookies
final prefs = await SharedPreferences.getInstance();
final savedCookies = cookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
await prefs.setString(cookieKey, savedCookies);
print("存储的 Cookies: $savedCookies");
// Step 3: 访问个人中心,获取该页面的 cookies
print("Step 3: 访问个人中心页面并记录 cookies...");
// 确保请求头带上所有 cookies
final personalCenterResponse = await dio.get(
personalCenterUrl,
options: Options(
headers: {'cookie': cookieHeader}, // 确保传递所有 cookie
),
);
print("______________________");
print(personalCenterResponse.data);
print("______________________");
// 获取个人中心页面的 cookies
final personalCookies = await cookieJar.loadForRequest(Uri.parse(personalCenterUrl));
final personalCookieHeader = personalCookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
print("Personal Center Cookies: $personalCookieHeader");
// 将个人中心的 cookies 记录下来
final allCookies = cookies + personalCookies;
final allCookiesHeader = allCookies.map((cookie) => '${cookie.name}=${cookie.value}').join('; ');
// 打印并保存所有 cookies
print("All Cookies: $allCookiesHeader");
await prefs.setString(cookieKey, allCookiesHeader);
return "Login and cookie retrieval successful";
} else {
return loginResponse.statusCode == 200 ? "Incorrect username or password" : "Login failed with status code: ${loginResponse.statusCode}";
}
尝试过手动控制cookie还是自动处理cookie都不行,个人中心页面会认为这是一个全新的请求并跳转到登录页面。
我实在不理解,为什么同样的逻辑,python能实现,但是别的语言都不行
ChatGPT说因为python是同步请求,dart是异步请求…但是我也设置了await
求大佬解答,鼓捣三天多了,死活搞不定,甚至不知道是哪里的原因