modified: __pycache__/get_info.cpython-310.pyc

modified:   __pycache__/kill_course.cpython-310.pyc
	modified:   __pycache__/single_course.cpython-310.pyc
	modified:   course_info.json
	modified:   demo.py
	modified:   get_info.py
	modified:   kill_course.py
	modified:   main.py
	modified:   single_course.py
main
JesterHey 9 months ago
parent 315d26af3a
commit a75444a931

@ -1,157 +1 @@
{
"7367": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7366": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7033": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7517": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7032": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7516": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7031": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7515": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"6349": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7436": {
"rate": 100,
"type": "\u5fc5\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"6937": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u672a\u8bc4\u5206"
},
"6938": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u672a\u8bc4\u5206"
},
"6991": {
"rate": 15,
"type": "\u57f9\u8bad",
"status": "\u672a\u5b66\u5b8c"
},
"6992": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"6993": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"6995": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"7006": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"7007": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"7010": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"7011": {
"rate": 100,
"type": "\u57f9\u8bad",
"status": "\u5df2\u5b66\u5b8c"
},
"7554": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7553": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7552": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7551": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7550": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7549": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7548": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7547": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7546": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7545": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
},
"7564": {
"rate": 100,
"type": "\u9009\u4fee",
"status": "\u5df2\u5b66\u5b8c"
}
}
{"6349": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7436": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7367": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7366": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7033": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7517": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7032": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7516": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7031": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7515": {"rate": 100, "type": "\u5fc5\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "6937": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "6938": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u672a\u8bc4\u5206"}, "6991": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u672a\u8bc4\u5206"}, "6992": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "6993": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "6995": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "7006": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "7007": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "7010": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "7011": {"rate": 100, "type": "\u57f9\u8bad", "status": "\u5df2\u5b66\u5b8c"}, "7554": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7553": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7552": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7551": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7550": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7549": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7548": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7547": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7546": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7545": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}, "7564": {"rate": 100, "type": "\u9009\u4fee", "status": "\u5df2\u5b66\u5b8c"}}

@ -1,4 +1,10 @@
from DrissionPage import ChromiumPage
from DrissionPage.common import *
page = ChromiumPage()
page.ele('tag:a@@text():是').click()
from collections import *
import json
info = json.load(open('course_info.json', 'r'))
cnt = defaultdict(list)
new_cnt = defaultdict(list)
for k, v in info.items():
new_cnt[v['type']].append((k,v['rate'],v['status'])) # 课程类型作为键课程id作为值
print(new_cnt)
for k,v in new_cnt.items():
print(k,v)

@ -4,35 +4,63 @@ from collections import *
import time
import json
from loguru import logger
import subprocess
# http://hnqmgc.17el.cn/grzx/
def get_info():
# 创建页面对象,并启动或接管浏览器
# 单独实现登录操作
def login(first:bool=True):
if not first:
return
# 先检查当前页面是否已经登录
page = WebPage()
# 跳转到登录页面
try:
page.get('http://hnqmgc.17el.cn/grzx/',retry=5,timeout=5,interval=1)
if page.ele('tag:div@@text():欢迎您,',timeout=3):
logger.info('当前页面已登录')
return
except BaseException:
logger.error('网络连接失败')
logger.info('准备登录')
if first:
try:
page.get('http://hnqmgc.17el.cn/grzx/',retry=5,timeout=5,interval=1)
except BaseException:
logger.error('网络连接失败')
# 定位到账号文本框,获取文本框元素
ele = page.ele('#userName') # #的意思是通过id定位元素
# 输入对文本框输入账号
ele.input('51140220050507901X')
# 定位到密码文本框并输入密码
page.ele('#password').input('hnqm123456')
# 定位到验证码文本框并输入验证码
inpcode = page.ele('#yzcode').text # 湖南青马太可爱了吧,验证码居然直接放在页面源码里:)
page.ele('#inpcode').input(inpcode)
# 点击登录按钮
page.ele('#btnLogin').click()
# 进入课程页面
page.ele('.wxtsBox-button').click() # 关闭提示页面
page.ele('#login_btn').click()
page.ele('@value=进入个人中心').click()
# 定位到账号文本框,获取文本框元素
ele = page.ele('#userName') # #的意思是通过id定位元素
# 输入对文本框输入账号
ele.input('51140220050507901X')
# 定位到密码文本框并输入密码
page.ele('#password').input('hnqm123456')
# 定位到验证码文本框并输入验证码
inpcode = page.ele('#yzcode').text # 湖南青马太可爱了吧,验证码居然直接放在页面源码里:)
page.ele('#inpcode').input(inpcode)
# 点击登录按钮
page.ele('#btnLogin').click()
page.wait.new_tab(3)
# 进入课程页面
try:
if page.ele('@onclick=cha()',timeout=3):
page.ele('@onclick=cha()').click()
# <img style="width: 25px;height: 25px;" src="/images/index/cha.png" alt="" srcset="">
elif page.ele('tag:img@@style=width: 25px;height: 25px;',timeout=3):
page.ele('tag:img@@style=width: 25px;height: 25px;').click()
except BaseException:
logger.error('不能进入课程页面')
subprocess.run(["python", __file__])
exit()
page.ele('#login_btn').click()
page.ele('@value=进入个人中心').click()
def get_info(first:bool=True):
# 创建页面对象,并启动或接管浏览器
page = WebPage()
# 登录
login(first)
# 提取课程信息
time.sleep(2)
page.ele('@value=0').click()
if not first:
page.refresh()
time.sleep(2)
page.ele('@value=0',timeout=3).click()
# 获取总页数
course_info = {}
# <div class="paginationjs-nav J-paginationjs-nav">1 / 4</div>

@ -12,7 +12,10 @@ def kill_course(again:bool=False):
for k, v in info.items():
if v['rate'] < 100:
cnt[v['type']].append((k,v['rate'])) # 课程类型作为键课程id作为值
print(cnt)
logger.info('{}'.format(cnt))
if not cnt:
logger.info('所有课程均已完成')
return
# 按必修-选秀-专题-培训执行刷课
must = cnt['必修']
elective = cnt['选修']

@ -4,6 +4,9 @@ from collections import *
from loguru import logger
import subprocess
from typing import *
from DrissionPage import ChromiumPage
from DrissionPage.common import *
import time
# 获取课程信息
get_info()
# 执行刷课
@ -15,11 +18,10 @@ kill_course()
1. 对于必修课存在3种情况:未完成已完成未答题
2. 对于其他课存在3种情况:未完成已完成未评分
'''
# 重新获取课程信息
def new_info() -> DefaultDict[str, List[Tuple[str,int,str]]]:
get_info()
new_info = json.load(open('info.json','r'))
get_info(first=False)
new_info = json.load(open('course_info.json','r'))
# 读取各个类别的课程状态
new_cnt = defaultdict(list)
for k, v in new_info.items():
@ -42,20 +44,44 @@ new_cnt = new_info()
not_judged = []
not_quiz = []
for k, v in new_cnt.items():
if v['status'] == '已完成':
continue
if v['status'] == '未评分':
not_judged.append(k)
else:
not_quiz.append(k)
for i in v:
if i[2] == '未评分':
not_judged.append((i[0],k))
elif i[2] == '未答题':
not_quiz.append(i[0],k)
# 展示提示信息
for i in not_judged:
logger.warning('存在未评分的课程:{}'.format(i))
# 实现自动评分
def auto_judge(course_id:str) -> None:
def auto_judge(course_id:str,course_type:str) -> None:
# 根据课程类型和id进行定位
j_page = ChromiumPage() # 接管当前页面
# 判定课程类别
if course_type == '必修':
j_page.ele('@value=1').click()
elif course_type == '选修':
j_page.ele('@value=2').click()
elif course_type == '专题':
j_page.ele('@value=4').click()
elif course_type == '培训':
j_page.ele('@value=5').click()
time.sleep(1)
trs = j_page.ele('#tbody').eles('tag:tr')
for tr in trs:
# 鉴别课程序号
if tr.ele('tag:td').text.split('\t')[0] == course_id:
# 进入评分页面
tr.ele('tag:button@@text():进入评分').click()
j_page.ele('x://*[@id="gradeDetail_score"]/label[1]/input').click()
j_page.ele('tag:a@@text():保存').click()
time.sleep(1)
pass
print(not_judged)
# 实现自动评分
for i in not_judged:
logger.warning('存在未答题的课程:{}'.format(i))
auto_judge(i[0],i[1])
logger.info('已完成对课程:{}的评分'.format(i[0]))
# 实现自动答题
pass
def auto_quiz(course_id:str) -> None:
pass

@ -82,17 +82,18 @@ def one_course(cid:str,ctype:str,crate:int,again:bool=False):
tab.ele('tag:a@@text():是').click()
except:
pass
# 有时候没有弹窗提示,用以下方式手动检测
for i in l:
if i != 100:
tab.ele('#normalModel_nodeList').eles('tag:div')[l.index(i)].click()
time.sleep(1)
try:
if tab.ele('c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path',timeout=2):
tab.ele('c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path').click()
except:
pass
time.sleep(60) # 每次监测间隔60秒
finally:
# 有时候没有弹窗提示,用以下方式手动检测
for i in l:
if i != 100:
tab.ele('#normalModel_nodeList').eles('tag:div')[l.index(i)+1].click()
time.sleep(1)
try:
if tab.ele('c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path',timeout=2):
tab.ele('c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path').click()
except:
pass
time.sleep(60) # 每次监测间隔60秒
break # なぜここにbreakがいるのですかあかしいなあ。
if __name__ == '__main__':

Loading…
Cancel
Save