前一阵子,我突发奇想撸了个自动修改 WIFI 密码功能的代码。

说白了就是用油猴自动执行 JS 代码,来自动控制和操作路由器管理页面,从而达到自动更新密码的目的。

参考文章:《历经艰难险阻,我搞定了自动修改路由器 WIFI 密码》

文章链接:https://www.sysadm.cc/index.php/xitongyunwei/841-after-a-lot-of-difficulties-i-resolved-issue-to-change-wifi-password-of-router-automatically


看过之前文章的小伙伴们应该知道,前文中我使用的是旧版 TP-Link 的路由器,其管理页面是旧式的,操作起来着实麻烦。

其中居然还用到了 frameset 这种极具复古风情的标签元素,让我又回味了一把不忍回忆的过往。

所以说,整个代码的实现过程中,充满了艰辛和痛苦。

不过好在TP-Link 新版路由器的管理界面较旧版的要精练简化得多,这也更方便我们定位、获取和操作这些标签元素。

现今流行使用的正是这种新版管理界面的路由器,所以对于大家来说,本文内容和代码更适合参考并且完全可以直接拿来使用。

最近正好新买了一台 TL-WDR8661AC2600 起步,一般家用无线没问题,就拿它演示了。

还多说啥,直接开干吧!


搞定自动登录

按下 F12 打开火狐的调试窗口,点选 查看器 来定位网页标签元素。

点击左侧的箭头图标,用鼠标来定位密码框。

取得密码框的 idlgPwd ,那么自动填入密码的代码就是这样。

// 填入密码
document.getElementById('lgPwd').value = '123456';
 


接着是获取 确定 按钮的 id ,为 loginSub ,编写点击确定的代码如下。

// 按下确定登录按钮
document.getElementById('loginSub').click();
 


定位密码修改框

成功登录管理页面后,我们就可以直接看到无线密码设定的地方。

既然第一个页面就放着密码修改的设定,那么我们直接去改不就完了?

哎,这么说也没啥问题,但这里需要注意一个小细节,就是我们务必要保证的的确确是定位到了这个页面。

啥意思?

大白话就是说,我们要先保证不会由于某种原因(比如说误点击)而导致跳转到了其他页面,否则我们是找找不到我们想要的密码修改框的。

所以,我们要先让代码定位一下这个页面,然后再考虑修改密码的问题。

那么问题来了,这个首页是从哪里定位的呢?


定位首页

通过观察,我们很容易地就知道,原来是通过点击下方一排方格图标来切换不同功能的网页的。

点击第一个“网络状态”这个图标,就可以定位首页。

OK,那么接下来就简单了,很容易地我们就可以获取到这个 div 标签元素的 idnetStateMbtn

div 吗,难道不应该是 button 之类的标签?

其实从它的 id 名称上也能看出来,它是充当了一个按钮的角色。

于是点击它的代码就应该是这个样子。

// 点击网络状态图标
document.getElementById('netStateMbtn').click();
 


修改并保存密码

定位首页 OK 后,我们就可以来考虑如何修改并保存密码了。

如前面所操作的那样,没有什么特别的悬念,定位密码输入框及保存按钮的 id ,分别是 hostWifiPwdBshostWifiSaveBs

填充密码及点击确定按钮的代码就可以这样写了。

// 修改 WIFI 密码
document.getElementById('hostWifiPwdBs').value = 'password';

// 点击保存
document.getElementById('hostWifiSaveBs').click();
 


事情到这儿似乎结束了,真的吗?

不然,其实还有一个小坑!

当你点击保存按钮时,系统会弹出警告提示你是否真的确定更新密码。

这个框挺讨厌的是吧,不过这也是程序通常的做法,确保用户没有误操作。

好了,既然它出现了,那么我们就必须想办法处理它。

打起精神,继续加油吧!


消灭警告提示框

当警告窗口出现后,我们就可以定位窗口中确定按钮的 id

纳尼?没有 id

果然可怕的事情发生了,它居然没有 id ,那还怎么玩?

哎,别慌哈,我发现它有个 class ,是 subBtn ok ,这个 class 能不能用来定位呢?

还好答案是肯定的,不过需要用到 getElementsByClassName


小伙伴们应该注意到了吧,是 Elements ,而不是 Element ,英文单词是复数。

这就意味着,它是用来获取一组元素的,那么得到的结果就不是单个的而是多个的,所以结果是通过数组的形式来表达。

OK,在这个页面中我们找不到第二个 classsubBtn ok 的标签元素来,所以这个确认按钮只能是数组的第一个成员了。

那么代码应该是这个样子吧。

// 关闭确认提示
document.getElementsByClassName('subBtn ok')[0].click();
 

用控制台可以测试一下代码是否正确。


完整参考代码及演示画面

由于考虑到诸多的程序问题(比如程序中断等),我们需要加入一些延迟、判断、比较等相应的代码用来完善整个程序。

此处举例,比如每天自动修改密码,密码的算法由你自己决定,可简单亦可复杂,只要你自己能猜出来而别人不那么容易猜出来就行。

还有其他一些需要考虑的问题,就由小伙伴们自行判断和完善代码吧。


以下参考代码基本可以实现这样一些功能:

  • 自动登录管理页面
  • 每天自动填充密码并保存
  • 密码算法为固定字符串加当天日期(比如 Sysadm20210606
  • 循环判断密码是否过期,并可确保路由器离线后再次上线仍能执行修改密码的功能


完整代码下载:

下载链接:https://pan.baidu.com/s/1rpV4vjiO8MmMUtmNDMQwDQ

提取码:

输入阅读密码,解锁隐藏内容...



★扫码关注公众号, 发送【000844】获取阅读密码


将代码保存到油猴中,刷新路由器页面即可开始执行。

关于油猴的操作,具体可以参考前文(本文开头有链接),也可以参考其他文章,此处暂不赘述。


// ==UserScript==
// TP-Link 路由器 型号 TL-WDR8661 测试通过
// @name         定时修改路由器 WIFI 密码
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  网管小贾的博客 / www.sysadm.cc
// @author       @网管小贾
// @match        http://192.168.1.1/
// @icon         https://www.google.com/s2/favicons?domain=89.251
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...

        //页面完全加载后运行
    window.onload=function autorun() {

        console.log('页面加载完毕,可以执行代码!!');

        Date.prototype.Format = function (fmt) {
            let o = {
                "M+": this.getMonth() + 1, //月份
                "d+": this.getDate(), //日
                "h+": this.getHours(), //小时
                "m+": this.getMinutes(), //分
                "s+": this.getSeconds(), //秒
                "q+": Math.floor((this.getMonth() + 3) / 3), //季度
                "S": this.getMilliseconds() //毫秒
            };
            if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
            for (let k in o) {
                if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
            }
            return fmt;
        };

        var currentDate = (new Date()).Format("yyyyMMdd");
        var checkDate = '';

        function changeWifi() {

            currentDate = (new Date()).Format("yyyyMMdd");

            if (currentDate != checkDate) {
                console.log('Different! - currentDate: ' + currentDate + ' | checkDate: ' + checkDate);

                setTimeout(function() {
                    try {
                        // 登录
                        document.getElementById('lgPwd').value = '123456';
                        document.getElementById('loginSub').click();
                    }
                    catch (e) {
                    }

                    setTimeout(function() {
                        try {

                            currentDate = (new Date()).Format("yyyyMMdd");

                            // 定位“网络状态”首页画面
                            document.getElementById('netStateMbtn').click();

                            setTimeout(function() {

                                try {
                                    // 避免重复修改
                                    if (document.getElementById('hostWifiPwdBs').value != 'Sysadm' + currentDate) {

                                        // 修改 WIFI 密码
                                        document.getElementById('hostWifiPwdBs').value = 'Sysadm' + currentDate;
                                        // 保存
                                        document.getElementById('hostWifiSaveBs').click();
                                        // 关闭确认提示
                                        document.getElementsByClassName('subBtn ok')[0].click();

                                        setTimeout(function() {
                                            checkDate = currentDate;
                                        }, 1000);

                                    }

                                }
                                catch (e) {
                                    checkDate = '';
                                }

                            }, 1000);

                        }
                        catch (e) {
                            checkDate = '';
                        }


                    }, 1000);

                }, 2000);

            } else {
                console.log('Same! - currentDate: ' + currentDate + ' | checkDate: ' + checkDate);
            }

        }

        var myVar;
        myVar = setInterval(changeWifi, 1 * 10 * 1000);
        // console.log(myVar);

    }

})();
 

动态效果演示:


写在最后

本着能动手绝不逼逼的原则,我简单粗暴地撸了这么一些低劣代码,各位见笑!

虽然自己想要的效果基本能够实现,但囿于自身水平,程序代码仍有诸多不足之处,万望各路大神指点一二。

那么各位小伙伴在实际使用的过程中,其最终效果能否真正满足实际需求呢?

希望大家都来说一说,聊聊自己的看法。

如果小伙伴们还有什么其他的奇思妙想,欢迎关注我,我们一起讨论。

最后祝大家不必再为被蹭网而烦恼,自己的无线路由器自己做主!


扫码关注@网管小贾,阅读更多

网管小贾的博客 / www.sysadm.cc



暂无评论

登录并提交评论

© 2020-present 网管小贾 | 微信公众号 @网管小贾
许可协议:CC-BY-NC 4.0 | 转载文章请注明作者出处及相关链接