-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from Colorfulshadow/experiment
first version worked on 23/9/11
- Loading branch information
Showing
4 changed files
with
195 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,73 @@ | ||
# buaa_course_enrollment | ||
·旨在自动化北京航空航天大学(BUAA)的课程选课过程。 | ||
# BUAA Course Enrollment Automation | ||
|
||
## 简介 | ||
|
||
**`buaa_course_enrollment.py`** 是一个专为北京航空航天大学(BUAA)设计的自动选课脚本。其主要功能是帮助学生在开放选课期间自动选择课程,减轻手动选课的负担和压力。脚本使用Python编写,结合了BeautifulSoup和requests库来实现自动登录和选课功能。 | ||
|
||
### 主要功能 | ||
|
||
- 自动登录北京航空航天大学的教务系统。 | ||
- 根据用户输入的课程类型和课程代码自动选择课程。 | ||
- 能够自动识别当前的学期,并根据学期修改相关参数。 | ||
- 在成功选课前持续尝试选课,提高选课成功率。 | ||
|
||
## 使用方式 | ||
|
||
### 安装必要的库 | ||
|
||
首先,确保你已经安装了Python和所需要的库: | ||
|
||
```bash | ||
pip install -r requirements | ||
``` | ||
|
||
### 配置脚本 | ||
|
||
1. 打开`buaa_course_enrollment.py`文件。 | ||
2. 修改脚本顶部的配置部分,填入你的账号、密码、课程类型、课程代码和对应序号。 | ||
|
||
```python | ||
USERNAME = '你的账号' | ||
PASSWORD = '你的密码' | ||
COURSE_TYPE = '你要选择的课程类型' | ||
COURSE_CODE = '你要选择的课程代码' | ||
SERIAL_CODE= '你要选择的课程序号' | ||
``` | ||
|
||
对应下图,1、2、3分别为COURSE_TYPE(可以在代码`TYPE_DICT`中找到)、COURSE_CODE和SERIAL_CODE(从001开始)。例如,我希望选择该图中高胜杰老师的足球课,我将填写: | ||
|
||
```python | ||
COURSE_TYPE = '体育' | ||
COURSE_CODE = 'B2E333070' | ||
SERIAL_CODE= '003' | ||
``` | ||
|
||
 | ||
|
||
### 运行脚本 | ||
|
||
在脚本所在的目录打开终端或命令提示符,然后运行以下命令: | ||
|
||
```bash | ||
python buaa_course_enrollment.py | ||
``` | ||
|
||
脚本将自动登录并开始尝试选课。成功选课后,它将退出。 | ||
|
||
## 注意事项 | ||
|
||
- 请确保在使用脚本之前已知晓并遵守北京航空航天大学的相关规定和政策。 | ||
- 脚本仅用于教育和学习目的,请勿用于任何非法或不道德的用途。 | ||
|
||
## 贡献 | ||
|
||
如果你有任何改进或功能增加的建议,请通过Pull Request或Issue来贡献。 | ||
|
||
## 许可 | ||
|
||
该项目根据[GNU GENERAL PUBLIC LICENSE许可证](LICENSE)进行许可。 | ||
|
||
## 特别感谢 | ||
|
||
本项目参考了[Cauchy1412](https://github.com/Cauchy1412)的[BUAAGetCourse](https://github.com/Cauchy1412/BUAAGetCourse)。 | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
requests==2.26.0 | ||
beautifulsoup4==4.10.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import time | ||
import requests | ||
from bs4 import BeautifulSoup | ||
from urllib.parse import quote | ||
import re | ||
from datetime import datetime | ||
|
||
# 设置配置变量 | ||
BASE_URL = 'http://jwxt.buaa.edu.cn:8080/ieas2.1' | ||
LOGIN_URL = 'https://sso.buaa.edu.cn/login?service=' + quote(BASE_URL + '/welcome', 'utf-8') | ||
USERNAME = '' | ||
PASSWORD = '' | ||
COURSE_TYPE = '' | ||
COURSE_CODE = '' | ||
SERIAL_CODE = '001' | ||
|
||
TYPE_DICT = { | ||
'一般专业': ('xslbxk', 'ZYL', 'xslbxk'), | ||
'核心专业': ('xslbxk', 'ZYL', 'xslbxk'), | ||
'核心通识': ('xslbxk', 'TSL', 'tsk'), | ||
'一般通识': ('xslbxk', 'TSL', 'qxrx'), | ||
'体育': ('xslbxk', 'TSL', 'ty') | ||
} | ||
VAR1, VAR2, VAR3 = TYPE_DICT[COURSE_TYPE] | ||
|
||
def get_current_term(): | ||
now = datetime.now() | ||
year = now.year | ||
month = now.month | ||
|
||
if month >= 8: | ||
term = f"{year}-{year+1}-1" | ||
short_term = f"{year}{(year+1) % 100}1" | ||
elif month <= 1: | ||
term = f"{year-1}-{year}-1" | ||
short_term = f"{(year-1) % 100}{year % 100}1" | ||
else: | ||
term = f"{year-1}-{year}-2" | ||
short_term = f"{(year-1) % 100}{year % 100}2" | ||
|
||
return term, short_term | ||
|
||
# 使用这个函数来设置RWH和pageXnxq | ||
term, short_term = get_current_term() | ||
RWH = f'{term}-{COURSE_CODE}-{SERIAL_CODE}' | ||
PAGE_XNXQ = short_term | ||
|
||
# 定义获取登陆令牌的函数 | ||
def get_login_token(session): | ||
r = session.get(LOGIN_URL) | ||
r.raise_for_status() | ||
soup = BeautifulSoup(r.content, 'html.parser') | ||
return soup.find('input', {'name': 'execution'})['value'] | ||
|
||
# 定义登陆的函数 | ||
def login(session): | ||
formdata = { | ||
'username': USERNAME, | ||
'password': PASSWORD, | ||
'execution': get_login_token(session), | ||
'type': 'username_password', | ||
'_eventId': 'submit', | ||
'submit': '登陆' | ||
} | ||
r = session.post(LOGIN_URL, data=formdata, allow_redirects=True) | ||
soup = BeautifulSoup(r.text, "html.parser") | ||
return not soup.find_all('div', class_='error_txt') | ||
|
||
# 定义提取隐藏项的函数 | ||
def get_hidden_items(text): | ||
item_pattern = re.compile(r'<input type="hidden" id=".*?" name="(.*?)"\s+value="(.*?)"') | ||
return {item.group(1): item.group(2) for item in item_pattern.finditer(text)} | ||
|
||
# 定义提取消息的函数 | ||
def extract_message(html_text): | ||
message_pattern = re.compile(r"alert\('(.+?)'\);") | ||
match = message_pattern.search(html_text) | ||
return match.group(1) if match else None | ||
|
||
# 定义选课的函数 | ||
def choose(session): | ||
list_url = f'{BASE_URL}/xslbxk/queryXsxkList?pageXkmkdm={VAR2}' | ||
response = session.post(list_url, allow_redirects=True) | ||
response.raise_for_status() | ||
|
||
payload = get_hidden_items(response.text) | ||
payload.update({ | ||
'pageXnxq': PAGE_XNXQ, | ||
'pageXklb': VAR3, | ||
'pageYcctkc': '1', | ||
'rwh': RWH | ||
}) | ||
|
||
response = session.post(f'{BASE_URL}/{VAR1}/saveXsxk', data=payload) | ||
message = extract_message(response.text) | ||
if message: | ||
print(message) | ||
if "选课成功" in message: | ||
exit() | ||
|
||
# 主循环 | ||
def main(): | ||
if (USERNAME == '' or | ||
PASSWORD == '' or | ||
COURSE_TYPE == '' or | ||
COURSE_CODE == '' or | ||
TEACHER_CODE == ''): | ||
|
||
print("请填写USERNAME, PASSWORD, COURSE_TYPE, COURSE_CODE 和 TEACHER_CODE的正确值。") | ||
exit() | ||
|
||
session = requests.Session() | ||
login(session) | ||
|
||
while True: | ||
choose(session) | ||
time.sleep(6) | ||
|
||
if __name__ == "__main__": | ||
main() |