Skip to content

Commit

Permalink
fix:update to version 2.0.1
Browse files Browse the repository at this point in the history
  • Loading branch information
GentleCP committed Aug 31, 2020
1 parent 6af953a commit 5dcc758
Show file tree
Hide file tree
Showing 14 changed files with 574 additions and 284 deletions.
65 changes: 47 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
# UCAS Helper
![python version](https://img.shields.io/badge/python-3.5%2B-blue)
![demo version](https://img.shields.io/badge/version-2.0.1-yellowgreen)

原本只是一时兴起,为了方便写的UCAS课程网站小助手,帮助我自己进行课程资源快速同步。
没想到后面随着功能的增加,项目也变得小有规模起来,因此将其开放给全体UCAS同学,小助手的使用方式在下面有介绍,
十分简便(需要一点对`python`环境的了解,百度`python`的安装即可),如果你觉得本项目对你有所帮助的话,
Expand Down Expand Up @@ -48,11 +51,18 @@

![](img/1.7.0.png)

# 2. 版本号

1.7.2

## 2.1 更新内容
# 2. 更新日志

- [2.0.1] 对整体代码进行了重构,解决因课程网站`http`,`https`协议切换导致的访问出错问题,
同时更改了项目接口,方便小白和专业人士操作。以前均通过可视化`UI`界面进行操作,现在用户可选择`UI`和命令行两种模式,具体见**5.3使用步骤**
对各个功能测试结果如下:
- [x] 课程资源同步
- [x] 分数查询
- [ ] 自动评教:由于课程网站评教操作关闭,尚未测试
- [ ] 校园网登录:由于不在学校,尚未测试
- [ ] 校园网账号破解:同上
> 未测试内容基本上沿用了之前的代码,按照常理不会出错,如果有问题,欢迎提出`issue`

- [1.7.2] 修复了因课程主站使用http协议导致的错误
> GKD的课程主站偶尔抽风,一会用https,一会用http,导致访问端口出现问题,现统一将用到的url放到`settings.py/URLS`中,
当主站修改应用协议时修改对应url的协议即可。例如`'base_url':'http://jwxk.ucas.ac.cn'`>`'base_url':'https://jwxk.ucas.ac.cn'`,
Expand Down Expand Up @@ -146,26 +156,45 @@

## 5.3 使用步骤

- 克隆本项目到本地
1. 克隆本项目到本地
```text
git clone https://github.com/GentleCP/UCASHelper.git
```
> 如果没有安装`git`,也可以直接下载源代码或者在`release`中下载我发布的最新版本
- 安装依赖包
2. 安装依赖包
```text
pip install -r requirements.txt
pip install -r requirements.txt # 强烈建议使用虚拟环境
conda env create -f environment.yml # 如果采用conda环境
```

- 运行ucashelper.py
```text
python ucashelper.py
```
> 到此就可以看到小白的操作窗口了
- 爆破账号
```text
python ucashelper.py hack
```
3. 自由选择`UI`界面操作或命令行直接运行,可通过`python ucashelper --help`获得参数帮助
- UI界面运行
```text
python ucashelper.py ui
```
- 同步课程资源
```text
python ucashelper.py down
```
- 自动评教
```text
python ucashelper.py assess
```
- 查询成绩
```text
python ucashelper.py grade
```
- 登录校园网
```text
python ucashelper.py login
```
- 登出校园网
```text
python ucashelper.py logout
```
- 爆破账号
```text
python ucashelper.py hack
```

# 6. 提问
对项目如有任何问题或修改意见,欢迎提交`issue`或者邮件私信给我~
185 changes: 185 additions & 0 deletions core/assess.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# -*- coding: utf-8 -*-
"""
-----------------Init-----------------------
Name: assess.py
Description:
Author: GentleCP
Email: [email protected]
WebSite: https://www.gentlecp.com
Date: 2020-08-31
-------------Change Logs--------------------
--------------------------------------------
"""
import logging
import re
import time
import requests

from bs4 import BeautifulSoup

from core.login import Loginer

class Assesser(Loginer):

def __init__(self, user_info, urls,assess_msgs):
super().__init__(user_info, urls)
self._logger = logging.getLogger("Assesser")
self._assess_msgs = assess_msgs
self.headers = {
'Connection': 'keep-alive',
'Accept': '*/*',
'Origin': 'http://jwxk.ucas.ac.cn',
'X-Requested-With': 'XMLHttpRequest',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Referer': 'http://jwxk.ucas.ac.cn/evaluate/evaluateCourse/165683',
'Accept-Encoding': 'gzip, deflate',
'Accept-Language': 'zh-CN,zh;q=0.9',
}
self._id_pattern = re.compile('/evaluate/.*?/(?P<id>.*?)$')
self._course_assess_url = None # 动态获取课程评估地址

def _get_course_ids(self):
# 获取课程评估url
try:
res = self._S.get(url=self._urls['view_url']['http'],timeout=5)
except requests.Timeout:
res = self._S.get(url=self._urls['view_url']['https'])

bs4obj = BeautifulSoup(res.text,'html.parser')
href = bs4obj.find('a',string=re.compile('.*学期$')).get('href')
self._course_assess_url = self._urls['base_url']['http'] + href
# 获取课程id
try:
res = self._S.get(self._course_assess_url,timeout=5)
except requests.Timeout:
self._course_assess_url = self._urls['base_url']['https'] + href
res = self._S.get(self._course_assess_url)

bs4obj = BeautifulSoup(res.text, 'html.parser')
urls = [url.get('href') for url in bs4obj.find_all('a', {'class': 'btn'})]
course_ids = []
for url in urls:
course_ids.append(self._id_pattern.search(url).groupdict()['id'])
return course_ids

def __assess_course(self,course_id):
try:
res = self._S.get(self._urls['base_evaluateCourse_url']['http'] + course_id,timeout=5)
except requests.Timeout:
res = self._S.get(self._urls['base_evaluateCourse_url']['https'] + course_id)

s = res.text.split('?s=')[-1].split('"')[0]
bs4obj = BeautifulSoup(res.text, 'html.parser')
radios = bs4obj.find_all('input', attrs={'type': 'radio'})
value = radios[0]['value']
data = {}
for radio in radios:
data[radio['name']] = value
textareas = bs4obj.find_all('textarea')
for textarea, asses_msg in zip(textareas,self._assess_msgs[0:-2]):
# 填写主观评价内容
item_id = textarea.get('id')
data[item_id] = asses_msg
subjectiveRadio = bs4obj.find('input', {'class':'required radio'}).get('id')
subjectiveCheckbox = bs4obj.find('input',{'class','required checkbox'}).get('id')
data['subjectiveRadio']= subjectiveRadio # 教室大小合适
data['subjectiveCheckbox']= subjectiveCheckbox # 自己需求和兴趣

try:
post_url = self._urls['base_saveCourseEval_url']['http'] + course_id + '?s=' + s
res = self._S.post(post_url, data=data,headers=self.headers,timeout=5)
except requests.Timeout:
post_url = self._urls['base_saveCourseEval_url']['https'] + course_id + '?s=' + s
res = self._S.post(post_url, data=data, headers=self.headers)
tmp = BeautifulSoup(res.text, 'html.parser')
try:
flag = tmp.find('label', attrs={'id': 'loginSuccess'})
if flag.string == '保存成功':
print('\033[1;45m{}评估结果:[success] \033[0m'.format(course_id))
else:
print('\033[1;45m{}评估结果:[fail],请手动重新评估该课 \033[0m'.format(course_id))

except AttributeError:
print('\033[1;45m{}评估结果:[fail],尝试重新评估 \033[0m'.format(course_id))
self.__assess_course(course_id)

def _assess_courses(self, course_ids):
self._logger.info('开始评估课程')
time.sleep(2)
for course_id in course_ids:
self.__assess_course(course_id)
self._logger.info('课程评估完毕')


def _get_teacher_ids(self):
# 通过课程评估url得到教师评估url
teacher_assess_url = self._course_assess_url.replace('course','teacher')
res = self._S.get(teacher_assess_url)
bs4obj = BeautifulSoup(res.text, 'html.parser')
urls = [url.get('href') for url in bs4obj.find_all('a', {'class': 'btn'})]
teacher_ids = []
for url in urls:
teacher_ids.append(self._id_pattern.search(url).groupdict()['id'])
return teacher_ids

def __assess_teacher(self, teacher_id):
try:
res = self._S.get(self._urls['base_evaluateTeacher_url']['http'] + teacher_id,timeout=5)
except requests.Timeout:
res = self._S.get(self._urls['base_evaluateTeacher_url']['https'] + teacher_id)

bs4obj = BeautifulSoup(res.text,'html.parser')
radios = bs4obj.find_all('input', attrs={'type': 'radio'})
value = radios[0]['value'] # 默认全5星好评
data = {}
for radio in radios:
data[radio['name']] = value
textareas = bs4obj.find_all('textarea')
for textarea, asses_msg in zip(textareas, self._assess_msgs[-2:]):
# 填写主观评价内容
item_id = textarea.get('id')
data[item_id] = asses_msg
data['subjectiveCheckbox'] = ''
data['subjectiveRadio'] = ''
try:
post_url = self._urls['base_url']['http'] + bs4obj.find('form', {'id': 'regfrm'},timeout=5).get('action')
res = self._S.post(post_url,data=data,headers = self.headers,timeout=5)
except requests.Timeout:
post_url = self._urls['base_url']['https'] + bs4obj.find('form', {'id': 'regfrm'}).get('action')
res = self._S.post(post_url, data=data, headers=self.headers)
tmp = BeautifulSoup(res.text, 'html.parser')
try:
flag = tmp.find('label', attrs={'id': 'loginSuccess'})
if flag.string == '保存成功':
print('\033[1;45m{}评估结果:[success] \033[0m'.format(teacher_id))
return
else:
print('\033[1;45m{}评估结果:[fail],请手动评估该教师 \033[0m'.format(teacher_id))

except AttributeError:
print('\033[1;45m{}评估结果:[fail],尝试重新评估 \033[0m'.format(teacher_id))
self.__assess_teacher(teacher_id)

def _assess_teachers(self, teacher_ids):
self._logger.info('开始评估教师')
for teacher_id in teacher_ids:
self.__assess_teacher(teacher_id)
self._logger.info('教师评估完毕')

def run(self):
self.login()
course_ids = self._get_course_ids()
self._assess_courses(course_ids)
teacher_ids = self._get_teacher_ids()
self._assess_teachers(teacher_ids)


import settings
if __name__ =='__main__':
assesser = Assesser(user_info=settings.USER_INFO,
urls=settings.URLS,
assess_msgs=settings.ASSESS_MSG)
assesser.run()
Loading

0 comments on commit 5dcc758

Please sign in to comment.