这篇文章上次修改于 366 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

每次来图书馆连 WLAN 都要认证,关键是下面有一个记住密码还是摆设,不仅勾上没效果,而且就连浏览器都不会自动填充,每次登录都要手动拿笔记本上面的横排键盘输学号密码,很是不爽,今天闲着无聊,就想写一个自动登录.

经过简单的观察发现,登录注销均使用 GET ,尝试去代码里找接口,看了一下放弃了,主要是看不懂(我太菜了),那就直接抄好了.

请求参数有这些

c: Portal
a: login
callback: dr1636865026654
login_method: 1
user_account: ,0,***
user_password: ***
wlan_user_ip: 172.20.65.60
wlan_user_ipv6: 
wlan_user_mac: 50EB716C0E71
wlan_ac_ip: 172.20.254.251
wlan_ac_name: BRAS
jsVersion: 3.3.1
_: 1636865000676

其中那两个长长的数字一看就是时间戳了,但单位是毫秒,我们需要关心的就是账号密码了,至于其他的无所谓.虽然话是这么说,但还是先获取一下时间戳吧 int(time.time()*1000) , Python 居然不支持浮点数取反,但这样就能获取到时间戳了.然后是填入账号密码,这个也简单,直接是明文的,如果加密的话我还得去找他的加密函数(话说直接用 GET+ 明文真的好吗?).

虽然不知道账号前的 ,0, 是什么东西,但照抄就好了.由于请求的参数有点多,而且还是键值对的形式,于是我就想到了通过字典( dict )来实现,果然有现成的办法,最后成品如下.

# Python版本:3.9.7

from urllib import request as urllib2
import urllib.parse as parse
import time

url = 'http://172.20.254.249:801/eportal/?'
ua_headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
now = int(time.time()*1000)

datas = {'c': 'Portal', 'a': 'login', 'callback': 'dr' +
         str(now-500), 'login_method': '1', 'user_account': ',0,****', 'user_password': '****',
         'wlan_user_ip': '172.20.65.60', 'wlan_user_ipv6': '', 'wlan_user_mac': '50EB716C0E71', 'wlan_ac_ip': '172.20.254.251', 'wlan_ac_name': 'BRAS', 'jsVersion': '3.3.1', '_': str(now)
         }

try:
    # 通过urllib2.Request()方法构造一个请求对象,拼接请求参数

    request = urllib2.Request(url+parse.urlencode(datas), headers=ua_headers)
    # 向指定的url地址发送请求,并返回服务器响应的类文件对象

    response = urllib2.urlopen(request)
    # 服务器返回的类文件对象支持python文件对象的操作方法

    html = response.read()
    print(html)
except:
    print('大失败!')

最后成品如下,由于是刚写的,不知道下次还能不能用

2021-11-14T06:48:16.png

11-18 补充:经过几天时间,这个脚本依然可以登录,或许是真的只需要两个参数,其他的无所谓吧.不排除别人做的这个系统本身就很简陋的原因.

12-21 补充:今天久违的又来了图书馆,发现脚本没用了,于是就去调试.发现原因是时间戳偏差的有点厉害 (服务器时间比我本地慢了差不多三分钟).

那就减三分钟吧!

于是又好了.