重理工疫情期间自动打卡JS实现(每日上报+体温上报)
疫情打卡背景
众所周知,机器的出现就是为了将人从大量重复的劳动中解救出来,再加上我一般都是在家的,身边的环境还是比较稳定的,因此我每天需要的上传的信息都是很稳定的,因此就想到新学的js来实现自动打卡,话不多说上正文。
打卡界面
这些就是我们需要做的东西了
网站分析
首先利用登陆界面拿到我们的cookie,这里的cookis是用ASP.NET常见的用户身份验证生成的,有效期只有 浏览会话结束时,因此我们每次都得登陆,稍加分析,我们就能知道他需要提交的内容格式。然后根据我们的账号密码等数据,得到我们所需要的cookie。这里的cookie在后面的提交数据界面需要用。
登陆网站
function Auto_Land() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/sso/login',
contents: {
rylxdm: 1,
yhbh: Username,
yhmm: Password,
},
headers: {
Origin: 'https://qd-yqcj.cqut.edu.cn',
Referer: 'https://qd-yqcj.cqut.edu.cn/',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
},
success: chunk => {
const Cookie1 = chunk.header['set-cookie'];
let temp = [];
Cookie1.forEach(Cookie1 => {
temp.push(Cookie1.split('; ')[0]);
});
Cookie += temp[0];
console.log(Cookie);
resolve('登陆成功');
},
error: err => {
reject(`登陆失败\n\n${err}`)
}
});
});
}
每日上报
接下来让我们分析每日上报界面,这里因为我尽力已经上报完毕,所以就已经今天进不去每日上报界面了。但是每日上报界面的代码还是被我通过爬虫手段爬取下来了
通过分析,我们可以得到我们所需要的提交的数据类型是json,
'dtk={"_danxuanti":[{"key":90,"value":"225"},
{"key":91,"value":"230"},{"key":92,"value":"235"},
{"key":93,"value":"240"},{"key":94,"value":"242"},
{"key":95,"value":"245"},{"key":96,"value":"247"},
{"key":97,"value":"255"}],
"_duoxuanti":[],
"_tiankongti":[],
"_diliweizhiti":[],
"_shijianti":[],
"_xingzhengquhuati":[]};
当然,只做到这里是远远不够的,通过分析源码,我们还发现Cookie里面还不止这些,还得有一个mrrw_version,因为只有yqrwbb <= mrrw_version,同时我们还得在内容里面加入yqrwdm: -1
来贴一下源码
function submit() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tjdtk',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Cookie,
},
contents: {
'yqrwdm': -1,
'dtk': '{"_danxuanti":[{"key":90,"value":"225"},{"key":91,"value":"230"},{"key":92,"value":"235"},{"key":93,"value":"240"},{"key":94,"value":"242"},{"key":95,"value":"245"},{"key":96,"value":"247"},{"key":97,"value":"255"}],"_duoxuanti":[],"_tiankongti":[],"_diliweizhiti":[],"_shijianti":[],"_xingzhengquhuati":[]}',
},
success: chunk => {
const res = JSON.parse(chunk.body);
console.log(res);
if (res.IsSuccessful) {
resolve('提交成功'+chunk.body)
} else {
reject('提交失败'+chunk.body)
}
},
error: err => {
reject(`提交失败\n\n${err}`)
}
});
});
}
这样每日打卡的界面就算是做好了,接下来我们来做每日体温上报
每日体温上报
老规矩,分析网页
通过分析,我们不难发现,网页数据是通过这个https://qd-yqcj.cqut.edu.cn/home/tj_mrtw来进行异步提交数据的,因此,我们要做的就是通过这个网站来POST数据,接着我们来分析需要提交的数据格式
,观察界面,我们发现需要提交的格式是
不难发现 ,grtw是表示提交的体温数据,id是个人信息,sbsd是代表早中晚的信息,接下来,我们还是“制作数据”,grtw是体温信息,我们只需要通过随机函数制作一个微小的波动即可,这里我制作的波动是36度左右,
注意:最后提交的数据得是1位小数的和Sring格式
var temperature = (36 + (Math.random() * (0.8))).toFixed(1);
至于sbsd就是早中晚的意思,因此,我们只需要分别让sbsd=1,2,3即可,最后的ID,通过分析网页,我们可以发现https://qd-yqcj.cqut.edu.cn/home/Get_mrtwtbxx网站,可以给与我们所需要的ID数据,至此,我们所需要的所有数据已经制作完毕,接下来,提交就完事了。
来,上源码
function Get_ID() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/Get_mrtwtbxx',
headers: {
Origin: 'https://qd-yqcj.cqut.edu.cn',
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Accept: 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
Cookie,
},
success: chunk => {
console.log(chunk.body);
const res = JSON.parse(chunk.body);
ID= res.id;
resolve(`今天的ID是:${ID}`)
},
error: err => {
reject(`获取ID失败\n\n${err}`)
}
});
});
}
function submit_wajtw() {
var temperature = (36 + (Math.random() * (0.8))).toFixed(1);
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tj_mrtw',
contents:
{
grtw: temperature.toString(),
id: ID,
sbsd: 3
},
headers: {
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Origin: 'https://qd-yqcj.cqut.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Accept: "application/json, text/plain, */*",
Cookie,
},
success: chunk => {
console.log(chunk.body);
const res = JSON.parse((chunk.body).toString());
if(res.IsSuccessful)
resolve(`晚间的体温是:${temperature}`)
},
error: err => {
reject(`提交失败\n\n${err}`)
}
});
});
}
部署代码
至此所有的工作,我们已经做完,最后我们当然不可能每天还来手动运行这个代码,这样与原来的签到不就一样了吗,这个时候我们可以把这串代码部署到我们的服务器上了通过crontab 定时工作就可以了。
结果展示
整体代码
const {HttpRequest} = require('./HttpRequest');
const Username = '*********';Password = '*******'
Cookie = 'dtk={"_danxuanti":[{"key":90,"value":"225"},{"key":91,"value":"230"},{"key":92,"value":"235"},{"key":93,"value":"240"},{"key":94,"value":"242"},{"key":95,"value":"245"},{"key":96,"value":"247"},{"key":97,"value":"255"}],"_duoxuanti":[],"_tiankongti":[],"_diliweizhiti":[],"_shijianti":[],"_xingzhengquhuati":[]};mrrw_version=1006;';
ID =1;
function Get_ID() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/Get_mrtwtbxx',
headers: {
Origin: 'https://qd-yqcj.cqut.edu.cn',
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Accept: 'application/json, text/plain, */*',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
Cookie,
},
success: chunk => {
console.log(chunk.body);
const res = JSON.parse(chunk.body);
ID= res.id;
resolve(`今天的ID是:${ID}`)
},
error: err => {
reject(`获取ID失败\n\n${err}`)
}
});
});
}
function Auto_Land() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/sso/login',
contents: {
rylxdm: 1,
yhbh: Username,
yhmm: Password,
},
headers: {
Origin: 'https://qd-yqcj.cqut.edu.cn',
Referer: 'https://qd-yqcj.cqut.edu.cn/',
Accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
},
success: chunk => {
const Cookie1 = chunk.header['set-cookie'];
let temp = [];
Cookie1.forEach(Cookie1 => {
temp.push(Cookie1.split('; ')[0]);
});
Cookie += temp[0];
console.log(Cookie);
resolve('登陆成功');
},
error: err => {
reject(`登陆失败\n\n${err}`)
}
});
});
}
function submit_zajtw() {
var temperature = (36 + (Math.random() * (0.8))).toFixed(1);
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tj_mrtw',
contents:
{
grtw: temperature.toString(),
id: ID,
sbsd: 1
},
headers: {
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Origin: 'https://qd-yqcj.cqut.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Accept: "application/json, text/plain, */*",
Cookie,
},
success: chunk => {
const res = JSON.parse(chunk.body);
if(res.IsSuccessful)
resolve(`早上的体温是:${temperature}`)
},
error: err => {
console.log('提交失败');
reject(`提交失败\n\n${err}`)
}
});
});
}
function submit_wujtw() {
var temperature = (36 + (Math.random() * (0.8))).toFixed(1);
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tj_mrtw',
contents:
{
grtw: temperature.toString(),
id: ID,
sbsd: 2
},
headers: {
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Origin: 'https://qd-yqcj.cqut.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Accept: "application/json, text/plain, */*",
Cookie,
},
success: chunk => {
console.log(chunk.body);
const res = JSON.parse((chunk.body).toString());
if(res.IsSuccessful)
resolve(`午间的体温是:${temperature}`)
},
error: err => {
reject(`提交失败\n\n${err}`)
}
});
});
}
function submit_wajtw() {
var temperature = (36 + (Math.random() * (0.8))).toFixed(1);
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tj_mrtw',
contents:
{
grtw: temperature.toString(),
id: ID,
sbsd: 3
},
headers: {
Referer: 'https://qd-yqcj.cqut.edu.cn/home/mrtw',
Origin: 'https://qd-yqcj.cqut.edu.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Accept: "application/json, text/plain, */*",
Cookie,
},
success: chunk => {
console.log(chunk.body);
const res = JSON.parse((chunk.body).toString());
if(res.IsSuccessful)
resolve(`晚间的体温是:${temperature}`)
},
error: err => {
reject(`提交失败\n\n${err}`)
}
});
});
}
function submit() {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'POST',
_url: 'https://qd-yqcj.cqut.edu.cn/home/tjdtk',
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
'Content-Type': 'application/json;charset=UTF-8',
Cookie,
},
contents: {
'yqrwdm': -1,
'dtk': '{"_danxuanti":[{"key":90,"value":"225"},{"key":91,"value":"230"},{"key":92,"value":"235"},{"key":93,"value":"240"},{"key":94,"value":"242"},{"key":95,"value":"245"},{"key":96,"value":"247"},{"key":97,"value":"255"}],"_duoxuanti":[],"_tiankongti":[],"_diliweizhiti":[],"_shijianti":[],"_xingzhengquhuati":[]}',
},
success: chunk => {
const res = JSON.parse(chunk.body);
console.log(res);
if (res.IsSuccessful) {
resolve('提交成功'+chunk.body)
} else {
reject('提交失败'+chunk.body)
}
},
error: err => {
reject(`提交失败\n\n${err}`)
}
});
});
}
function sendToMe(text, desp) {
return new Promise((resolve, reject) => {
HttpRequest({
type: 'GET',
_url: 'https://sc.ftqq.com/*****************.send',
_query_string: {
text,
desp,
},
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
},
success: chunk => {
var ens =JSON.parse(chunk.body);
if (ens.data.errno=== 0) {
console.log("Server酱推送成功");
resolve('Server酱推送成功')
} else {
reject('Server酱推送失败')
}
},
error: err => {
reject(`Server酱推送失败\n\n${err}`)
}
})
});
}
function toMarkDown(text) {
console.log(text);
return text + '\n\n'
}
function getNowFormatDate() {
var date = new Date();
var year = date.getFullYear();
var month = date.getMonth() + 1;
var strDate = date.getDate();
var hour = date.getHours();
var minute = date.getMinutes();
var second = date.getSeconds();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
return year + "-" + month + "-" + strDate + '\n\n'+hour+':' + minute + ':' + second;
}
(() => {
let desp = '';
const md = toMarkDown;
desp += md('开始自动登录');
desp+= md(getNowFormatDate());
Auto_Land()
.then(data => {
desp += md(data);
return submit();
})
.then(data => {
desp += md(data);
return Get_ID();
})
.then(data => {
desp += md(data);
desp += md('早间打卡体温上传正常');
return submit_zajtw();
})
.then(data => {
desp += md(data);
desp += md('午间打卡体温上传正常');
return submit_wujtw();
})
.then(data => {
desp += md(data);
desp += md('晚间打卡体温上传正常');
return submit_wajtw();
})
.then(data => {
desp += md(data);
return Promise.resolve();
})
.then(() => {
return sendToMe('健康打卡通知', desp);
})
.catch(err => {
desp += toMarkDown(err);
return sendToMe('健康打卡出错', desp);
})
.catch(err => {
console.log(err);
})
})();