本项目适用于与 TamperMonkey 用户脚本对接
解决公共题库失效或接口风控导致的无法搜题,同时解决学习通前端页面字体加密的问题
使用抓包和反编译取得“学小易” 客户端(已弃用) 微信小程序的搜题接口,用于转发搜题请求返回脚本正确答案,从而代替公共题库接口
- Python3.6+
- 任何基于 chrome/firefox 的浏览器
- TamperMonkey 插件
- TamperMonkey 学习通自动刷课用户脚本
pip install -r requirement.txt
修改config.yaml
中的配置
- host:服务端绑定地址
- port:服务端接口
- enable_cache:是否启用搜题缓存
- xxy_open_id:“学小易 APP”微信小程序接口的 session(请通过抓包提取请求头中的
wx-open-id
字段
这里以用户脚本:超星学习通网课助手|视频挂机考试答题|全网聚合题库每日自动更新适用于几乎所有专业科目|完全免费永久使用【网课通用版】 举例,其他类似脚本请参考下文自行修改
将该用户脚本中的搜题API改成你的服务端 host:port,同时注释掉原公共题库 API,这里用192.168.1.3:88
举例
var setting = {
//tiku: 'http://api.muketool.com'
tiku: '192.168.1.3:88/'
......
并把服务端 host 加入用户脚本的跨域白名单
// @connect api.muketool.com
// @connect api2.muketool.com
// @connect 192.168.1.3
接着,需要破解字体加密(加密后的效果如下
需向脚本中添加以下两个函数
// 拾取加密字体
function getSecFont() {
return $("style[type='text/css']").text().match(/'(data:application\/font-ttf;.*?)'/)[1]
}
// 解密全部字体
function decryptAll() {
let secFont = getSecFont(),
encryptTexts = $('.TiMu').find('div.font-cxsecret,.font-cxsecret a');
// 遍历加密字体项
encryptTexts.each(function() {
let dstText = $(this);
GM_xmlhttpRequest({
method: 'POST',
url: `${setting.tiku}/decrypt`,
headers: {
'Content-type': 'application/json',
},
data: JSON.stringify({secFont: secFont, dstText: dstText.text().trim()}),
responseType: 'json',
onload: function (xhr) {
if (xhr.status == 200) {
dstText.text(xhr.response.srcText);
dstText.removeClass('font-cxsecret');
}
}
});
});
}
并在合适的位置调用decryptAll()
函数
......
setting.lose = setting.num = 0;
setting.data = parent._data = [];
setting.over = '<button style="margin-right: 10px;">跳过此题</button>';
setting.curs = $('script:contains(courseName)', top.document).text().match(/courseName:\'(.+?)\'|$/)[1] || $('h1').text().trim() || '无';
setting.loop = setInterval(findAnswer, setting.time);
var tip = ({
undefined: '任务点排队中', null: '等待切换中'
})[setting.tip];
tip && setting.div.children('div:eq(0)').data('html', tip).siblings('button:eq(0)').click();
decryptAll(); // 在这里添加
......
启动服务端
python3 app.py
服务端启动后将在指定 ip 上监听端口,这里为192.168.1.3:88
* Serving Flask app 'app' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on all addresses.
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://192.168.1.3:88/ (Press CTRL+C to quit)
浏览器启动修改好的 TamperMonkey 用户脚本,进入学习通答题/考试页面,即可开始自动搜题
方法:POST
请求体(application/x-www-form-urlencoded):
question=目标题目
响应(application/json):
{
"code": 1, // 响应状态 1: 成功 -1: 失败
"messsage": "", // 错误信息
"data": "", // 搜题结果
"hit": true // 是否命中题目缓存
}
方法:POST
请求体(application/json):
{
"secFont": "", // 密钥字体 base64
"dstText": "" // 目标密文本字符串
}
响应(application/json):
{
"srcText": "" // 源文本字符串
}