树维教务简易导入
简介
教程文字不多,请耐心逐行读完!!!
请在电脑浏览器上进行操作!!!
这个项目提供的工具能快速导出树维教务的课程信息,进而导入到 WakeUp课程表 中。点这里下载最新版本的 WakeUp课程表。本项目受 eastpiger 的项目启发,在此向他表示感谢,如果方便的朋友可以给他点个 Star!
本教程在新 Edge 浏览器和 Chrome浏览器 上经过测试,如果使用其它浏览器请自行摸索。
步骤
1. 打开课表页面
在浏览器打开学校的树维教务,登录,然后打开到查看课表的页面。
2. 打开浏览器的开发者工具
在课表页面按 F12
键打开开发者工具
。
一定是要在课表页面按!
一定是要在课表页面按!
一定是要在课表页面按!
3. 在控制台粘贴代码
新弹出来的窗口就是开发者工具
,界面如下图所示:
可以看到界面顶部有元素
、控制台
等几个标签,切换到控制台
,会看到下方区域开头会有个>
符号,将以下代码完整复制到控制台然后回车:
/* Blob.js
* A Blob implementation.
* 2014-07-24
*
* By Eli Grey, http://eligrey.com
* By Devin Samarin, https://github.com/dsamarin
* License: MIT
* See https://github.com/eligrey/Blob.js/blob/master/LICENSE.md
*/
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
(function (a) { a.URL = a.URL || a.webkitURL; if (a.Blob && a.URL) { try { new Blob; return } catch (d) { } } var c = a.BlobBuilder || a.WebKitBlobBuilder || a.MozBlobBuilder || (function (p) { var g = function (z) { return Object.prototype.toString.call(z).match(/^\[object\s(.*)\]$/)[1] }, y = function m() { this.data = [] }, w = function i(B, z, A) { this.data = B; this.size = B.length; this.type = z; this.encoding = A }, q = y.prototype, v = w.prototype, s = p.FileReaderSync, e = function (z) { this.code = this[this.name = z] }, r = ("NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR").split(" "), u = r.length, l = p.URL || p.webkitURL || p, t = l.createObjectURL, f = l.revokeObjectURL, k = l, o = p.btoa, j = p.atob, h = p.ArrayBuffer, n = p.Uint8Array, x = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/; w.fake = v.fake = true; while (u--) { e.prototype[r[u]] = u + 1 } if (!l.createObjectURL) { k = p.URL = function (A) { var z = document.createElementNS("http://www.w3.org/1999/xhtml", "a"), B; z.href = A; if (!("origin" in z)) { if (z.protocol.toLowerCase() === "data:") { z.origin = null } else { B = A.match(x); z.origin = B && B[1] } } return z } } k.createObjectURL = function (A) { var B = A.type, z; if (B === null) { B = "application/octet-stream" } if (A instanceof w) { z = "data:" + B; if (A.encoding === "base64") { return z + ";base64," + A.data } else { if (A.encoding === "URI") { return z + "," + decodeURIComponent(A.data) } } if (o) { return z + ";base64," + o(A.data) } else { return z + "," + encodeURIComponent(A.data) } } else { if (t) { return t.call(l, A) } } }; k.revokeObjectURL = function (z) { if (z.substring(0, 5) !== "data:" && f) { f.call(l, z) } }; q.append = function (D) { var F = this.data; if (n && (D instanceof h || D instanceof n)) { var E = "", A = new n(D), B = 0, C = A.length; for (; B < C; B++) { E += String.fromCharCode(A[B]) } F.push(E) } else { if (g(D) === "Blob" || g(D) === "File") { if (s) { var z = new s; F.push(z.readAsBinaryString(D)) } else { throw new e("NOT_READABLE_ERR") } } else { if (D instanceof w) { if (D.encoding === "base64" && j) { F.push(j(D.data)) } else { if (D.encoding === "URI") { F.push(decodeURIComponent(D.data)) } else { if (D.encoding === "raw") { F.push(D.data) } } } } else { if (typeof D !== "string") { D += "" } F.push(unescape(encodeURIComponent(D))) } } } }; q.getBlob = function (z) { if (!arguments.length) { z = null } return new w(this.data.join(""), z, "raw") }; q.toString = function () { return "[object BlobBuilder]" }; v.slice = function (C, z, B) { var A = arguments.length; if (A < 3) { B = null } return new w(this.data.slice(C, A > 1 ? z : this.data.length), B, this.encoding) }; v.toString = function () { return "[object Blob]" }; v.close = function () { this.size = 0; delete this.data }; return y }(a)); a.Blob = function (j, h) { var l = h ? (h.type || "") : ""; var g = new c(); if (j) { for (var k = 0, e = j.length; k < e; k++) { if (Uint8Array && j[k] instanceof Uint8Array) { g.append(j[k].buffer) } else { g.append(j[k]) } } } var f = g.getBlob(l); if (!f.slice && f.webkitSlice) { f.slice = f.webkitSlice } return f }; var b = Object.getPrototypeOf || function (e) { return e.__proto__ }; a.Blob.prototype = b(new a.Blob()) }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
/* FileSaver
* A saveAs() FileSaver implementation.
* 1.3.2
* 2016-06-16 18:25:19
*
* By Eli Grey, http://eligrey.com
* License: MIT
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
*/
var saveAs = saveAs || function (e) { "use strict"; if (typeof e === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) { return } var t = e.document, n = function () { return e.URL || e.webkitURL || e }, r = t.createElementNS("http://www.w3.org/1999/xhtml", "a"), o = "download" in r, a = function (e) { var t = new MouseEvent("click"); e.dispatchEvent(t) }, i = /constructor/i.test(e.HTMLElement) || e.safari, f = /CriOS\/[\d]+/.test(navigator.userAgent), u = function (t) { (e.setImmediate || e.setTimeout)(function () { throw t }, 0) }, s = "application/octet-stream", d = 1e3 * 40, c = function (e) { var t = function () { if (typeof e === "string") { n().revokeObjectURL(e) } else { e.remove() } }; setTimeout(t, d) }, l = function (e, t, n) { t = [].concat(t); var r = t.length; while (r--) { var o = e["on" + t[r]]; if (typeof o === "function") { try { o.call(e, n || e) } catch (a) { u(a) } } } }, p = function (e) { if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)) { return new Blob([String.fromCharCode(65279), e], { type: e.type }) } return e }, v = function (t, u, d) { if (!d) { t = p(t) } var v = this, w = t.type, m = w === s, y, h = function () { l(v, "writestart progress write writeend".split(" ")) }, S = function () { if ((f || m && i) && e.FileReader) { var r = new FileReader; r.onloadend = function () { var t = f ? r.result : r.result.replace(/^data:[^;]*;/, "data:attachment/file;"); var n = e.open(t, "_blank"); if (!n) e.location.href = t; t = undefined; v.readyState = v.DONE; h() }; r.readAsDataURL(t); v.readyState = v.INIT; return } if (!y) { y = n().createObjectURL(t) } if (m) { e.location.href = y } else { var o = e.open(y, "_blank"); if (!o) { e.location.href = y } } v.readyState = v.DONE; h(); c(y) }; v.readyState = v.INIT; if (o) { y = n().createObjectURL(t); setTimeout(function () { r.href = y; r.download = u; a(r); h(); c(y); v.readyState = v.DONE }); return } S() }, w = v.prototype, m = function (e, t, n) { return new v(e, t || e.name || "download", n) }; if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) { return function (e, t, n) { t = t || e.name || "download"; if (!n) { e = p(e) } return navigator.msSaveOrOpenBlob(e, t) } } w.abort = function () { }; w.readyState = w.INIT = 0; w.WRITING = 1; w.DONE = 2; w.error = w.onwritestart = w.onprogress = w.onwrite = w.onabort = w.onerror = w.onwriteend = null; return m }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content); if (typeof module !== "undefined" && module.exports) { module.exports.saveAs = saveAs } else if (typeof define !== "undefined" && define !== null && define.amd !== null) { define("FileSaver.js", function () { return saveAs }) }
/* icsFormatter
* A file generator
* By eastpiger
*/
var fileGenerator = function () {
'use strict';
if (navigator.userAgent.indexOf('MSIE') > -1 && navigator.userAgent.indexOf('MSIE 10') == -1) {
console.log('Unsupported Browser');
return;
}
return {
/**
* Download calendar using the saveAs function from filesave.js
* @param {string} filename Filename
* @param {string} ext Extention
*/
'download': function (filename, ext) {
var courseJson = JSON.stringify(rawdata);
if (courseJson) {
var targetStr = "index.js');"
var afterIndex = courseJson.indexOf(targetStr)
if (afterIndex != -1) {
courseJson = courseJson.substring(afterIndex + targetStr.length)
}
ext = (typeof ext !== 'undefined') ? ext : '.html';
filename = (typeof filename !== 'undefined') ? filename : '教务';
var blob = new Blob([courseJson], { type: 'attachment/csv;charset=utf-8' });
saveAs(blob, filename + ext);
} else return false;
}
};
};
var VER = "0.6";
var rawdata = undefined;
var mode = undefined;
function check_page_allow() {
try {
rawdata = $($("#frmright")[0].contentDocument).find("#div-table tbody")[0];
mode = "grad";
return true;
}
catch (error) {
console.error(error);
}
try {
rawdata = table0;
mode = "eams";
if (window.hasOwnProperty("unitCount")) {
rawdata.unitCount = unitCount;
}
return true;
}
catch (error) {
console.error(error);
}
try {
rawdata = window.table0;
if (window.hasOwnProperty("unitCount")) {
rawdata.unitCount = unitCount;
}
if (typeof rawdata !== 'undefined') {
mode = "eams";
return true;
}
}
catch (error) {
console.error(error);
}
var ifrs = $("iframe");
if (ifrs.length > 0) {
for (var i = 0; i < ifrs.length; i++) {
try {
rawdata = ifrs[i].contentWindow.table0;
if (ifrs[i].contentWindow.hasOwnProperty("unitCount")) {
rawdata.unitCount = ifrs[i].contentWindow.unitCount;
}
if (typeof rawdata !== 'undefined') {
mode = "eams";
return true;
}
} catch (error) {
console.error(error);
}
}
}
}
if (Boolean(window.$) && check_page_allow()) {
var semester = "";
try {
if (mode == "eams") {
semester = $("#courseTableForm input.calendar-text")[0].value;
} else if (mode == "grad") {
semester = $($($("#frmright")[0].contentDocument).find("#div-table div")[0]).html();
}
} catch (error) {
var semester = "教务";
}
window.icsObj = fileGenerator();
window.icsObj.download(semester);
if (mode == "eams")
setTimeout("alert('文件' + semester + '.html' + '已经保存到默认的下载文件夹中,请按照教程完成后续操作。————WakeUp课程表')", 500)
else if (mode == "grad")
alert("这种类型还没有支持哦,请到App关于页面联系开发者适配")
} else {
alert('加载失败,请确认是否进入正确页面!');
}
顺利的话,浏览器会自动下载一个 HTML 文件。如果提示还未适配,就按照提示跟开发者取得联系。如果没有文件下载,请先确定教务是不是真的是树维教务,树维教务长啥样在视频教程里有描述。如果确定真的是树维教务但还是不能自动下载文件,点这里把控制台截图发给我们。
4. 导入到 WakeUp课程表(不要点回自己学校)
找到浏览器自动下载的 HTML 文件(默认应该是在「下载」文件夹),然后通过 QQ 发送到手机 QQ 上,直接在 QQ 接收界面打开,选「用其他应用打开」,然后找到有我们 Logo 的「导入到课程表」。会弹窗让你选择是否覆盖当前课程表,如果选择新建一个的话,导入成功后记得点右上角三个点切换课表。
然后点「选择学校/教务类型」,找到「树维教务(简易导入)」,
这里是关键!!!按照本教程导入,必须选「树维教务(简易导入)」,而不是自己的学校。
选「树维教务(简易导入)」!
选「树维教务(简易导入)」!
选「树维教务(简易导入)」!
选择后,然后点右下角的下载按钮,应该就能成功导入了。