JesterHey 9 months ago
commit ad7633f1a7

@ -0,0 +1,18 @@
{
"configurations": [
{
"name": "macos-clang-arm64",
"includePath": [
"${workspaceFolder}/**"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "${default}",
"cppStandard": "${default}",
"intelliSenseMode": "macos-clang-arm64",
"compilerArgs": [
""
]
}
],
"version": 4
}

@ -0,0 +1,13 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Runner: Debug Session",
"type": "lldb",
"request": "launch",
"args": [],
"cwd": "/Users/xuxiaolan/PycharmProjects/cyan_horse",
"program": "/Users/xuxiaolan/PycharmProjects/cyan_horse/build/Debug/outDebug"
}
]
}

@ -0,0 +1,59 @@
{
"C_Cpp_Runner.cCompilerPath": "clang",
"C_Cpp_Runner.cppCompilerPath": "clang++",
"C_Cpp_Runner.debuggerPath": "lldb",
"C_Cpp_Runner.cStandard": "",
"C_Cpp_Runner.cppStandard": "",
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 JesterHey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1,34 @@
# 🍏青马助手🐎 beta1.0
## 前置要求
- 环境变量 Python >= 3.8
- Chrome浏览器
## 使用方法
1. __下载程序(以下任选其一)__
- 使用git克隆仓库
```git clone https://github.com/JesterHey/cyan_horse.git```
- 下载压缩包
[点此下载](https://github.com/JesterHey/cyan_horse/archive/refs/heads/main.zip)
2. __安装所需库__
在文件夹位置进入终端页面(压缩包下载者需解压后进入),输入代码:
```pip install requirements.txt```
后等待下载完毕
3. __运行__
输入
```python main.py```
后程序自动开始执行,按要求填入信息即可
## 常见问题
1. 网络连接错误
> 首先检查网络是否通畅,然后关闭程序后再重新按照上述步骤重新打开程序即可。
2. 提示找不到元素或元素不存在
> 由于青马网站加载限制和网络波动,有时候页面尚未完全加载时程序便开始执行下一步操作,因而产生此错误,解决方法同上。
3. 课程信息识别有误
> 问题产生原因在于读取课程信息时网站刷新不及时导致漏读,这回使得刷课时反复刷已经完成的课,解决方法也同上。
其他问题请在Issues中提出
## TO DO
- [ ] 完成自动答题模块
## 免责声明
使用程序即表示您愿意承担相应后果,原作者概不对其负责。

File diff suppressed because one or more lines are too long

@ -1,10 +0,0 @@
import json
dic = json.load(open('course_info.json', 'r'))
l1 = [ i for i in dic.keys() if dic[i]['type'] == '选修' ]
l2 = [ i for i in dic.keys() if dic[i]['type'] == '必修' ]
l3 = [ i for i in dic.keys() if dic[i]['type'] == '专题' ]
l4 = [ i for i in dic.keys() if dic[i]['type'] == '培训' ]
print(len(l1))
print(len(l2))
print(len(l3))
print(len(l4))

@ -37,16 +37,21 @@ def login(first: bool = True, init: bool = False, username: str = None, pwd: str
# 定位到账号文本框,获取文本框元素
ele = page.ele('#userName') # 的意思是通过id定位元素
# 输入对文本框输入账号
ele.input(username)
# 定位到密码文本框并输入密码
page.ele('#password').input(pwd)
# 定位到验证码文本框并输入验证码
inpcode = page.ele('#yzcode').text # 湖南青马太可爱了吧,验证码居然直接放在页面源码里:)
page.ele('#inpcode').input(inpcode)
# 点击登录按钮
page.ele('#btnLogin').click()
page.wait.new_tab(3)
try:
# 输入对文本框输入账号
ele.input(username)
# 定位到密码文本框并输入密码
page.ele('#password').input(pwd)
# 定位到验证码文本框并输入验证码
inpcode = page.ele('#yzcode').text # 湖南青马太可爱了吧,验证码居然直接放在页面源码里:)
page.ele('#inpcode').input(inpcode)
# 点击登录按钮
page.ele('#btnLogin').click()
page.wait.new_tab(3)
if page.ele('@onclick=cha()',timeout=3):
pass
except BaseException:
logger.error('登录错误,请检查输入的账号密码是否正确!')
# 进入课程页面
try:
if page.ele('@onclick=cha()', timeout=3):

@ -1 +0,0 @@
{"username": "51140220050507901X", "password": "hnqm123456", "study_type": "\u7f51\u7edc\u6587\u660e\u5fd7\u613f\u8005"}

@ -0,0 +1,3 @@
DrissionPage==4.0.4.8
DrissionPage==4.0.4.11
loguru==0.7.2

@ -49,11 +49,14 @@ def one_course(cid: str, ctype: str, crate: int, again: bool = False):
print('当前课程已完成')
cur_page.close_tabs(tabs_or_ids=[tab])
# 进入后,获得当前视频的完成率,决定操作方式
if tab.ele('tag:a@@text():继续学习', timeout=2):
tab.ele('tag:a@@text():继续学习').click()
else:
tab.ele(
'c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path').click()
try:
if tab.ele('tag:a@@text():继续学习', timeout=2):
tab.ele('tag:a@@text():继续学习').click()
else:
tab.ele(
'c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path').click()
except BaseException:
pass
# 建立循环,检测当前视频是否完播
'''
<div id="normalModel_nodeList" style="max-height:550px;overflow:auto;">
@ -85,14 +88,17 @@ def one_course(cid: str, ctype: str, crate: int, again: bool = False):
try:
if tab.ele('tag:div@@text():本小结已经学习完,是否进入下一节?', timeout=2):
tab.ele('tag:a@@text():是').click()
except:
except BaseException:
pass
finally:
# 有时候没有弹窗提示,用以下方式手动检测
for i in l:
if i != 100:
tab.ele('#normalModel_nodeList').eles(
'tag:div')[l.index(i)].click()
pers = tab.eles('.percentText')
for p in pers:
if int(p.text[:-1]) < 100:
p.click()
break
time.sleep(1)
try:
if tab.ele('c:#normalModel_video > xg-start > div.xgplayer-icon-play > svg > path', timeout=2):
@ -101,6 +107,7 @@ def one_course(cid: str, ctype: str, crate: int, again: bool = False):
except:
pass
time.sleep(60) # 每次监测间隔60秒
break # なぜここにbreakがいるのですかあかしいなあ。

Loading…
Cancel
Save