南京师范大学网络自动登录脚本(Python版)

研究生期间每天来到实验室的第一件事就是打开电脑,打开浏览器登录校园网,然后开始办公。虽说也只是简简单单的一两步,但时间长了也会觉得乏味,最重要的是一点也不极客范。于是便萌生了编写一个脚本来实现开机自动登录校园网的想法。这里总结一下我使用Python实现的过程。

分析js

分析登录页面的JS代码,找到登录函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
function loginAction(){
if($("#username").val()==""){
asyncbox.alert("请输入用户名","登录出错");
return;
}
if($("#password").val()==""){
asyncbox.alert("请输入密码","登录出错");
return;
}
//getUserLineInfo();
getLoginInfo();
};

这里面又调用了一个getLoginInfo()函数,再继续查看这个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function getLoginInfo(){
var username = $("#username").val();
var password = $("#password").val();
$.ajax({
data : {username:username,password:password},
type : "POST",
url : url+"login",
//url:"json/login.json",
dataType : 'json',
error : function(data) {
asyncbox.alert(data.reply_msg,"登录错误");
},
success : function(data) {
saveCookie();
if((data.reply_code==1) || (data.reply_code==6)){
window.location.href='http://www.njnu.edu.cn';
}else{
asyncbox.alert(data.reply_msg,"登录错误");
}
}
});
};

所以登录过程是用POST实现的,url为:

1
http://portal.njnu.edu.cn/portal_io/login

提交的参数为:

1
data : {username:username,password:password}

知道以上这些信息便可以使用Python的Requests库实现脚本登录了。

Python实现脚本登陆

以下是Python简单的实现:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env python
#-*- coding:utf8 -*-
#coding=utf-8
#Author: Yayu.Jiang
import requests
username = ''
password = ''
url = "http://portal.njnu.edu.cn/portal_io/login"
res = requests.post(url, data={"username": username, "password": password})

只需配置好用户名和密码,然后执行脚本即可登录校园网。

完善脚本

以上几行代码就是自动登录脚本的核心代码了,我们当然不能满足于如此简陋的脚本,让我们来完善一下这个脚本吧。

登陆成功/失败提示

自动登录脚本,怎么能没有登录成功或失败的提示呢。在Linux终端运行脚本时,可以通过print输出提示,而在Windows下,我们则更希望通过弹窗的形式来提示是否登录成功。于是我们使用了一个叫ctypes的库来实现windows下的弹窗,同时需要platform库来检测当前的操作系统是Linux还是Windows。

首先导入这两个库:

1
2
import ctypes
import platform

然后完善代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/env python
#-*- coding:utf8 -*-
#coding=utf-8
#Author: Yayu.Jiang
import requests
import ctypes
import platform
MessageBox = ctypes.windll.user32.MessageBoxW
title = u"NJNU Auto Login"
username = ''
password = ''
url = "http://portal.njnu.edu.cn/portal_io/login"
try:
res = requests.post(url, data={"username": username, "password": password})
except Exception as e: # 连接异常终止程序
msg = "[Error]"+unicode("Connection aborted.")
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
exit()
result = res.json()
if(result['reply_code']==1 or result['reply_code']==6):
msg = "[Success] "+ unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
else:
msg = "[Fail] " + unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)

设置重连接

当网络不好时,连接可能会被断开,此时我们希望程序能够自动检测到网络异常,并尝试再次连接,且连接失败的时候每隔几秒钟尝试一次。同时考虑到这些参数应该设置成可选项,即能够通过设置参数开启或关闭。我们将脚本进行封装,编写成一个类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!/usr/bin/env python
#-*- coding:utf8 -*-
#coding=utf-8
#Author: Yayu.Jiang
import requests
import ctypes
import platform
import time
MessageBox = ctypes.windll.user32.MessageBoxW
title = u"NJNU Auto Login"
username = '151302052'
password = '250318'
url = "http://portal.njnu.edu.cn/portal_io/login"
class AutoLogin():
username = '' # 用户名
password = '' # 密码
ok_msg = True # 指示登录成功时是否弹窗提示
faile_msg = True # 指示登录成功时是否弹窗提示
reconn = True # 指示登录失败后是否尝试重新连接
reconn_time = 5 # 失败重连间隔时间(s)
reconn_max_num = 3 # 失败重连最大次数
keep_online = True # 指示是否后台工作,在网络断开时候重新尝试连接
keep_intvl = 600 # 心跳时间(s),监测是否正常联网
def login(self):
try:
res = requests.post(url, data={"username": username, "password": password})
except Exception as e: # 连接异常终止程序
msg = "[Error]"+unicode("Connection aborted.")
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return None
result = res.json()
if((result['reply_code']==1 or result['reply_code']==6) and self.ok_msg):
msg = "[Success] "+ unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return None
elif(self.faile_msg):
msg = "[Fail] " + unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return result
def isOnline(self):
try:
res = requests.get("http://www.baidu.com", timeout=5)
if res.status_code == 200:
return True
else:
return False
except Exception as e:
return False
if __name__ == '__main__':
autologin =AutoLogin()
# 后台保持在线模式
while (True):
# 定时发送心跳监测是否正常联网
if (autologin.isOnline()):
if (not autologin.keep_online):
break
else:
time.sleep(autologin.keep_intvl)
continue
count = 0
while (count < autologin.reconn_max_num):
result = autologin.login()
if (result == None): break
if (not autologin.reconn): break
if (result['reply_code'] == 1 or result['reply_code'] == 6): break
count += 1
time.sleep(autologin.reconn_time)
# 后台保持在线模式关闭,则直接退出
if (not autologin.keep_online): break
time.sleep(autologin.keep_intvl)
exit()

添加配置文件

为了脚本的封装性更好,我们并不希望上面的那些设置需要从脚本代码中直接修改。因此进一步优化代码,将配置参数提取到一个配置文件中,以后我们只需要修改配置文件中的参数就可以实现开启/关闭弹窗提示功能、失败重连功能、掉线重连过程。

说做就做,首先在同一目录下新建config.ini文件,添加以下配置信息:

1
2
3
4
5
6
7
8
9
10
11
12
[user]
username = 000000
password = 000000
[setting]
ok_msg = yes
faile_msg = yes
reconn = yes
reconn_time = 1
reconn_max_num = 3
keep_online = no
keep_intvl = 5

读取config.ini文件需要ConfigParser库,首先导入库

1
import ConfigParser

配置文件的读取应在AutoLogin类初始化时,所以实现AutoLogin类的__init__函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def __init__(self):
if os.path.exists('config.ini'):
cf = ConfigParser.ConfigParser()
cf.read(configure)
try:
self.username = cf.get("user","username")
self.password = cf.get("user","password")
self.ok_msg = cf.getboolean("setting","ok_msg")
self.faile_msg = cf.getboolean("setting","faile_msg")
self.reconn = cf.getboolean("setting","reconn")
self.reconn_time = cf.getint("setting","reconn_time")
self.reconn_max_num = cf.getint("setting", "reconn_max_num")
self.keep_online = cf.getboolean("setting", "keep_online")
self.keep_intvl = cf.getint("setting", "keep_intvl")
except Exception as e:
if(platform.system() == "Windows"):
MessageBox(None, "[Configure Error] "+ unicode(e.message), title, 0)
else:
print(u'配置文件错误:'+ e.message)
else:
msg = u"[Error] " + u"Configure File Not Found"
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
exit()

说明:

  1. 将配置文件中keep_online设置为yes,程序将常驻后台,若非网络状况差到经常掉线的情况,可以不必开启。
  2. keep_intvl是检测网络状况的心跳时间,单位(秒),表示每隔对应的秒数检验一次网络状况。

最终代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
#-*- coding:utf8 -*-
#coding=utf-8
#Author: Yayu.Jiang
import os
import ConfigParser
import requests
import ctypes
import platform
import time
MessageBox = ctypes.windll.user32.MessageBoxW
title = u"NJNU Auto Login"
configure = u'config.ini'
url = "http://portal.njnu.edu.cn/portal_io/login"
class AutoLogin():
username = '' # 用户名
password = '' # 密码
ok_msg = True # 指示登录成功时是否弹窗提示
faile_msg = True # 指示登录成功时是否弹窗提示
reconn = True # 指示登录失败后是否尝试重新连接
reconn_time = 5 # 失败重连间隔时间(s)
reconn_max_num = 3 # 失败重连最大次数
keep_online = True # 指示是否后台工作,在网络断开时候重新尝试连接
keep_intvl = 600 # 心跳时间(s),监测是否正常联网
def __init__(self):
if os.path.exists(configure):
cf = ConfigParser.ConfigParser()
cf.read(configure)
try:
self.username = cf.get("user","username")
self.password = cf.get("user","password")
self.ok_msg = cf.getboolean("setting","ok_msg")
self.faile_msg = cf.getboolean("setting","faile_msg")
self.reconn = cf.getboolean("setting","reconn")
self.reconn_time = cf.getint("setting","reconn_time")
self.reconn_max_num = cf.getint("setting", "reconn_max_num")
self.keep_online = cf.getboolean("setting", "keep_online")
self.keep_intvl = cf.getint("setting", "keep_intvl")
except Exception as e:
if(platform.system() == "Windows"):
MessageBox(None, "[Configure Error] "+ unicode(e.message), title, 0)
else:
print(u'配置文件错误:'+ e.message)
else:
msg = u"[Error] " + u"Configure File Not Found"
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
exit()
def login(self):
try:
res = requests.post(url, data={"username": self.username, "password": self.password})
except Exception as e: # 连接异常终止程序
msg = "[Error]"+unicode("Connection aborted.")
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return None
result = res.json()
if((result['reply_code']==1 or result['reply_code']==6) and self.ok_msg):
msg = "[Success] "+ unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return None
elif(self.faile_msg):
msg = "[Fail] " + unicode(result['reply_msg'])
if (platform.system() == "Windows"):
MessageBox(None, msg, title, 0)
else:
print(msg)
return result
def isOnline(self):
try:
res = requests.get("http://www.baidu.com", timeout=5)
if res.status_code == 200:
return True
else:
return False
except Exception as e:
return False
if __name__ == '__main__':
autologin =AutoLogin()
# 后台保持在线模式
while (True):
# 定时发送心跳监测是否正常联网
if (autologin.isOnline()):
if (not autologin.keep_online):
break
else:
time.sleep(autologin.keep_intvl)
continue
count = 0
while (count < autologin.reconn_max_num):
result = autologin.login()
if (result == None): break
if (not autologin.reconn): break
if (result['reply_code'] == 1 or result['reply_code'] == 6): break
count += 1
time.sleep(autologin.reconn_time)
# 后台保持在线模式关闭,则直接退出
if (not autologin.keep_online): break
time.sleep(autologin.keep_intvl)
exit()

生成exe

考虑到不是所有人的电脑上都安装了Python,因此为了推广这个脚本,特将Python转换成exe,方便大家使用。
将Python脚本转打包成exe,这里使用的是PyInstaller,官方推荐使用pip安装:

1
pip install pyinstaller

安装好pyinstaller之后,在控制台运行:

1
pyinstaller NJNU_Auto_Login.py

看到以下输出表示已经打包成功:

最终生成以下文件:

exe可执行文件就在dist文件夹中,将配置文件config.ini拷贝到该文件下,双击NJNU_Auto_Login.exe即可运行。

去除小黑框

我们发现,程序虽然能很好的运行,但是每次运行时都会弹出黑窗:

作为强迫症的我怎么能忍,必须搞掉:

dict文件夹中新建start.vbs文件,添加以下内容

1
CreateObject("WScript.Shell").Run "cmd /c NJNU_Auto_Login.exe",0

start.vbs发送到桌面快捷方式,直接双击运行,我们惊喜的发现,小黑窗不见啦

设置开机自启动

使用win+R,打开运行,输入shell:startup并回车

将前面说到的start.vbs快捷方式复制到打开的文件夹中便可以实现开机自启动了,从此告别手动登录校园网。

最后附上打包好的exe文件,大家下载后只需修改config.ini中的用户名和密码,然后将start.vbs快捷方式按照以上说明发送到Startup文件夹中即可。

下载:
NJNU_Auto_Login.zip

若本文对您有帮助,请打赏鼓励本人!
---------------- End ----------------
扫二维码
扫一扫,使用手机查看

扫一扫,使用手机查看

QQ