本文介绍如何使用Node.js结合JavaScript脚本,在本地定时自动打开指定网站、填写账号密码登录,并触发签到与签退按钮的click事件。通过计算时间差设置定时器,实现固定时间的自动化打卡操作,适用于公司内部考勤系统的自动化处理。
此前曾介绍过利用TamperMonkey屏蔽CSDN广告的技巧,核心在于分析网页结构并通过代码操作DOM。本次思路一致,需先观察网页结构定位目标按钮,随后触发其
click事件。以下以公司考勤系统为例,演示相关自动化操作。建议读者具备基础的HTML与JavaScript知识。
签到流程与自动化思路
首先,梳理正常签到流程包含以下步骤:
- 访问网站页面
- 完成身份登录
- 点击“签到”按钮
上述每个步骤均可通过编写代码自动执行。
定时机制与核心逻辑
0. 定时机制的实现
此段代码为核心逻辑,通过计算当前时间与设定时间的差值来确定定时器时长。理解该逻辑后,后续步骤均基于定时器触发回调函数实现,相对简单。
// user setting
const SIGN_IN_TIME = "09:30:00"; // 签到时间
const SIGN_OUT_TIME = "20:00:00"; // 签退时间
// code implementation
logTime("code start running");
const now = new Date();
const today = now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
var signInTime = +new Date(`${today} ${SIGN_IN_TIME}`);
logTime("signInTime", new Date(signInTime));
var signOutTime = +new Date(`${today} ${SIGN_OUT_TIME}`);
logTime("signOutTime", new Date(signOutTime));
// diff in or out
if (now > signInTime && now < signOutTime) {
// ready to sign out for today
console.log("Seconds to sign out for today: " + (signOutTime - now) / 1000);
setTimeout(callback, signOutTime - now);
} else {
// ready to sign in for tomorrow
signInTime = +signInTime + 60 * 60 * 24 * 1000;
console.log("Seconds to sign in for tomorrow: " + (signInTime - now) / 1000);
setTimeout(callback, signInTime - now);
}
function logTime(str, time = new Date()) {
console.log(`${str} -> ${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`);
}
自动打开网站与登录实现
1. 定时自动打开网站
多数网站设有“长时间未操作自动退出”机制,因此需在预定打卡时刻再打开网页。在本地运行Node程序,利用定时器控制流程:
const open = require('open');
logTime("Start Runing");
// user setting
const SIGN_IN_TIME = "09:30:00";
const SIGN_OUT_TIME = "20:20:00";
// code implementation
const openBrowser = async () => {
await open('http://172.10.80.42');
};
logTime("code start running");
const now = new Date();
const today = now.getFullYear() + "-" + (now.getMonth() + 1) + "-" + now.getDate();
var signInTime = +new Date(`${today} ${SIGN_IN_TIME}`);
logTime("signInTime", new Date(signInTime));
var signOutTime = +new Date(`${today} ${SIGN_OUT_TIME}`);
logTime("signOutTime", new Date(signOutTime));
// diff in or out
if (now > signInTime && now < signOutTime) {
// ready to sign out for today
console.log("Seconds to sign out for today: " + (signOutTime - now) / 1000);
setTimeout(openBrowser, signOutTime - now);
} else {
// ready to sign in for tomorrow
signInTime = +signInTime + 60 * 60 * 24 * 1000;
console.log("Seconds to sign in for tomorrow: " + (signInTime - now) / 1000);
setTimeout(openBrowser, signInTime - now);
}
function logTime(str, time = new Date()) {
console.log(`${str} -> ${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`);
}
2. 自动登录流程
关键在于定位需要填入内容的DOM元素。
(function() {
'use strict';
// login
document.querySelector("#loginid").value = "用户名";
document.querySelector("#userpassword").value = "密码";
document.querySelector("#login").click();
})();
按钮点击与时间控制
3. 定时点击按钮
此步需精准定位按钮元素,可通过检查元素功能逐步查找。同时,需设定明确的签到与签退时间,仅在固定时间点执行自动操作,避免频繁登录触发系统警报。
(function() {
'use strict';
// user setting
const SIGN_IN_TIME = "09:00:00";
const SIGN_OUT_TIME = "21:00:00";
// code implementation
logTime("code start running");
const now = new Date();
const today = now.getFullYear()+"-"+(now.getMonth()+1)+"-"+now.getDate();
var signInTime = +new Date(`${today} ${SIGN_IN_TIME}`);
logTime("signInTime", new Date(signInTime));
var signOutTime = +new Date(`${today} ${SIGN_OUT_TIME}`);
logTime("signOutTime", new Date(signOutTime));
// diff in or out
if(now > signInTime && now < signOutTime) {
// ready to sign out for today
console.log("Seconds to sign out for today: " + (signOutTime - now)/1000);
setTimeout(signInorSignOut, signOutTime - now);
} else {
// ready to sign in for tomorrow
signInTime = +signInTime + 60 * 60 * 24 * 1000;
console.log("Seconds to sign in for tomorrow: " + (signInTime - now)/1000);
setTimeout(signInorSignOut, signInTime - now);
}
// signInorSignOut
function signInorSignOut(){
logTime(`signInButton clicked!`);
// 重点就在这儿了,找到网站的签到按钮#signInButton,并触发他的点击事件
document.querySelector("#signInButton").click();
}
function logTime(str, time=new Date()){
console.log(`${str} -> ${time.getHours()}:${time.getMinutes()}:${time.getSeconds()}`);
}
})();
程序运行与总结
4. 流程结束
整套操作完成后即可运行。每日下班时,无论提前离开或晚到,均需启动本地程序:
node timer.js
至此,关于利用JS脚本实现网站定时签到与签退功能的介绍完毕。如需了解更多相关js定时操作内容,可搜索本站往期文章或浏览后续文章,感谢支持。