所需环境python(用于http.post,也可用其他工具代替)
新建bat文件连接pppoe.bat
,输入以下内容:
RASDIAL 宽带连接 username passwd
其中,宽带连接
是pppoe的名称,username
和passwd
是上网的账号和密码。
然后新建bat文件断开pppoe.bat
,输入以下内容:
rasdial 宽带连接 /DISCONNECT
首先使用chrome打开Web认证页面,以本校为例,打开网页http://10.6.8.2:904
,按F12或右键-检查,进入Network选项卡:
在Web认证页中点击登陆,就可以捕获本机发出的http请求,我只抓到一个包,如果有多个需要自己筛选找到post账号密码的包。
分析抓到的包,主要关注General,Request Headers和Form Data。
一边分析抓到的包,一边构造python代码,新建python文件auto-login.py:
import requests
import time
class INST(object):
def __init__(self, username, password):
pass
def _get_page(self):
pass
def _login(self, request):
pass
因为抓包显示用到了cookie,因此我们在_get_page()
方法中,利用session
保存会话,然后在_login()
方法中将登陆请求post给服务器。
__init__():
def __init__(self, username, password):
self.username = username
self.password = password
self.UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36'
request = self._get_page()
for i in range(5):
if request.status_code != 200:
time.sleep(2)
request = self._get_page()
if request.status_code == 200:
self._login(request)
将之前抓包看到的Request Headers - User Agent的内容赋值给self.UA
。
考虑到网络可能出问题导致临时打不开登陆页,因此我在这里设置如果获取登陆页失败,等待2秒重新获取,循环5次。如果觉得不需要可以去掉for
循环。
最后调用登陆函数self._login()
。
_get_page():
def _get_page(self):
login_page = 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&'
header = {
'Referer' : 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&',
'User-Agent' : self.UA
}
self.session_requests = requests.Session()
r = self.session_requests.get(login_page, headers=header)
#soup = BeautifulSoup(r.content, 'html.parser')
#print(r.text)
return r
login_page
填登陆页网址。
构造好报文头header
后,初始化一个Session
,然后利用该Session
发get
报文:
r = self.session_requests.get(login_page, headers=header)
这样我们就保存了cookie,登陆时可以自动提交。
_login():
def _login(self, request):
login_url = 'http://10.6.8.2:904/include/auth_action.php'
header = {
'Connection' : 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': '10.6.8.2:904',
'Origin': 'http://10.6.8.2:904',
'Referer': 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1',
'User-Agent': self.UA,
'X-Requested-With': 'XMLHttpRequest'
}
post_data = {
'action' : 'login',
'username': self.username,
'password': self.password,
'ac_id' : 1,
'save_me' : 1,
'ajax' : 1
}
#login
r = self.session_requests.post(login_url, data=post_data, headers=header)
_login()
方法主要任务是构造报文头以及form
表单,注意要按照之前抓到的Request Headers 和 Form Data的内容构造,提交的网址应当是General - Request URL中的网址(与获取登录页_get_page()
中的网址不同)。
报文头和form表单中有一些项目不是必须的,可以自己尝试,我提交以上数据即可登陆(由于cookie每次都会改变,而我们在session
中已将cookie保存,因此cookie项不用管)。
这样就完成了自动Web认证的Python代码,完整代码如下:
#-*- coding:utf-8 -*-
import requests
import time
class INST(object):
def __init__(self, username, password):
self.username = username
self.password = password
self.UA = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.167 Safari/537.36'
request = self._get_page()
for i in range(5):
if request.status_code != 200:
time.sleep(2)
request = self._get_page()
if request.status_code == 200:
self._login(request)
def _get_page(self):
login_page = 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&'
header = {
'Referer' : 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&',
'User-Agent' : self.UA
}
self.session_requests = requests.Session()
r = self.session_requests.get(login_page, headers=header)
#soup = BeautifulSoup(r.content, 'html.parser')
#print(r.text)
return r
def _login(self, request):
login_url = 'http://10.6.8.2:904/include/auth_action.php'
header = {
'Connection' : 'keep-alive',
'Content-Type': 'application/x-www-form-urlencoded',
'Host': '10.6.8.2:904',
'Origin': 'http://10.6.8.2:904',
'Referer': 'http://10.6.8.2:904/srun_portal_pc.php?ac_id=1',
'User-Agent': self.UA,
'X-Requested-With': 'XMLHttpRequest'
}
post_data = {
'action' : 'login',
'username': self.username,
'password': self.password,
'ac_id' : 1,
'save_me' : 1,
'ajax' : 1
}
#login
r = self.session_requests.post(login_url, data=post_data, headers=header)
def main():
un = 'username'
pw = 'passwd'
INST(un,pw)
if __name__ == '__main__':
main()
运行python文件,测试是否能够进行网页认证,由于是通过发送http报文认证的,因此浏览器看不到响应,可以在认证后随便打开一个网页,能上去就ok。
新建bat文件网页认证.bat
,输入以下代码:
python ./auto-login.py
我们的校园网,只要一连接pppoe就会弹出认证页面,我没有想到很好的办法来自动关闭该页面,只能采取比较麻烦的方式,如果哪位朋友有更好的方法,欢迎交流!
我这里采用将默认浏览器设置为不常用的,以Edge为例。在完成认证后查找是否有Edge进程,若有则kill
掉。因为我通常不用Edge,因此杀掉该进程通常没有其他影响。
新建bat文件杀Edge进程.bat
,输入以下代码:
@echo off
tasklist|find /i "MicrosoftEdge.exe"
if %errorlevel%==0 goto kill
else goto end
:kill
taskkill /im MicrosoftEdge.exe /f
:end
将上面的2个MicrosoftEdge.exe
替换为默认浏览器的进程名即可。
为了能够全自动登陆,需要将以上文件连接起来。将以上文件全部放在同一目录下,并新建文件连接校园网.vbs
,输入以下代码:
On Error Resume Next
set ws=WScript.CreateObject("WScript.Shell")
Set ObjH=CreateObject("MSXML2.XMLHTTP")
Dim Count:Count = 5 '定义一个变量
Do Until Count = 0 '直到Count变量为0时,否则一直循环
ws.Run "C:\批处理文件\自动连接校园网\连接pppoe.bat",0
wscript.sleep 1000*3
'测试能否访问登陆页面
ObjH.Open "GET","http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&",False
ObjH.Send()
If ObjH.StatusText="OK" Then
'能够访问登陆页
ws.Run "C:\批处理文件\自动连接校园网\网页认证.bat",0
'退出循环
Exit Do
Else
'错误
ws.Run "C:\批处理文件\自动连接校园网\断开pppoe.bat",0
wscript.sleep 1000*3
End If
Count = Count -1
Loop
ws.Run "C:\批处理文件\自动连接校园网\杀Edge进程.bat",0
将ObjH.Open "GET","http://10.6.8.2:904/srun_portal_pc.php?ac_id=1&",False
中的网址替换为Web认证页网址。这里每一步我都设置了延迟,可以根据自己的需要修改。
在测试过程中,曾出现pppoe连接成功,但认证页无法获取的情况,发现断开pppoe后重新连接就正常了,因此我这里设置如果获取不到认证页,则断开pppoe然后重复连接,循环5次。
注意如果要加入计划任务,则所有路径必须要用绝对路径,如果不需要则用./
即可。
双击该vbs文件即可,这样就实现了一键后台运行,且没有小黑框出现!
连接校园网.vbs
& 开机启动 & 创建计划任务C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
中创建连接校园网.vbs
的快捷方式(将文件加入开始菜单),即可让cortana认识该文件。C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp
中创建快捷方式即可