综述

最近山大软件园校区QLSC_STU无线网掉线掉的厉害,连上之后平均十分钟左右掉线一次,很是让人心烦,还能不能愉快地上自习了?能忍吗?反正我是不能忍了,嗯,自己动手,丰衣足食!写个程序解决掉它!

假若你不能连这个无线,那就照照思路啦~

决战前夕

首先我们看一下那个验证页面是咋样滴,上个图先

嘿,这界面还算可以把,需要我们输入的东西就是俩,一个就是学号,另一个是身份证号后六位,然后就可以登录,享受免费的无线网啦。

不过不知道谁设置了个登录时长,一段时间后就会掉线了,于是,自动模拟登陆系统就要应运而生啦。

来,我们先点击一下连接,看一下浏览器怎么工作的。

按下F12,监听网络,我们点击第一个响应,也就是login.jsp,看一下。我们具体看一下headers,里面form提交了什么东西,真的是茫茫多的数据啊。嗯,一目了然POST的数据和提交的地址。 让我们来分析几个数据吧:

ClientIP:当前客户端的IP地址,在山大软件园校区这个地址是211.87开头的

timeoutvalue:连接等待时间,也就是俗话说的timeout

StartTime:登录时间,也就是在你登录的那一刻的时间戳,这个时间戳是13位的,精确到了毫秒,不过一般是10位的,我们加3个0就好了

shkOvertime:登录持续时间,这个数据默认是720,也就是12分钟之后,登录就失效了,自动掉线,我们可以手动更改

username:学号

password:密码,也就是我们身份证号后六位

我们需要在登录的时候把form表单中的所有信息都POST一下,然后就可以完成登录啦。 万事俱备,只欠东风,来来来,程序写起来!

一触即发

说走咱就走啊,天上的星星参北斗啊!

登陆地址:Request URL:http://192.168.8.10/portal/login.jsp?Flag=0

首先,我们需要验证一下IP地址,先写一个获取IP地址的函数,首先判断当前IP是不是211.87开头的,如果是的话,证明连接的IP是有效的。 首先我们写一个获取本机IP的方法:

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
self.ip_pre = "211.87"    
#获取本机无线IP
    def getIP(self):
        local_iP = socket.gethostbyname(socket.gethostname())
        if self.ip_pre in str(local_iP):
            return str(local_iP)
        ip_lists = socket.gethostbyname_ex(socket.gethostname())
 
        for ip_list in ip_lists:
            if isinstance(ip_list, list):
                for i in ip_list:
                    if self.ip_pre in str(i):
                        return str(i)
            elif type(ip_list) is types.StringType:
                if self.ip_pre in ip_list:
                    return ip_list

这个方法利用了gethostbyname和gethostbyname_ex方法,获取了各个网卡的IP地址,遍历一下,找到那个211.87开头的IP,返回 接下来,获取到IP之后,我们便可以构建form,然后进行模拟登陆了。

 
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
#模拟登录
    def login(self):
        print self.getCurrentTime(), u"正在尝试认证QLSC_STU无线网络"
        ip = self.getIP()
        data = {
            "username": self.username,
            "password": self.password,
            "serverType": "",
            "isSavePass": "on",
            "Submit1": "",
            "Language": "Chinese",
            "ClientIP": self.getIP(),
            "timeoutvalue": 45,
            "heartbeat": 240,
            "fastwebornot": False,
            "StartTime": self.getNowTime(),
            #持续时间,超过这个时间自动掉线,可进行设置
            "shkOvertime": self.overtime,
            "strOSName": "",
            "iAdptIndex": "",
            "strAdptName": "",
            "strAdptStdName": "",
            "strFileEncoding": "",
            "PhysAddr": "",
            "bDHCPEnabled": "",
            "strIPAddrArray": "",
            "strMaskArray": "",
            "strMask": "",
            "iDHCPDelayTime": "",
            "iDHCPTryTimes": "",
            "strOldPrivateIP": self.getIP(),
            "strOldPublicIP": self.getIP(),
            "strPrivateIP": self.getIP(),
            "PublicIP": self.getIP(),
            "iIPCONFIG":0,
            "sHttpPrefix": "http://192.168.8.10",
            "title": "CAMS Portal"
        }
        #消息头
        headers = {
            'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',
            'Host': '192.168.8.10',
            'Origin': 'http://192.168.8.10',
            'Referer': 'http://192.168.8.10/portal/index_default.jsp?Language=Chinese'
        }
        post_data = urllib.urlencode(data)
        login_url = "http://192.168.8.10/portal/login.jsp?Flag=0"
        request = urllib2.Request(login_url, post_data, headers)
        response = urllib2.urlopen(request)
        result = response.read().decode('gbk')

比较多的内容就在于form表单的数据内容以及请求头,后来利用urllib2的urlopen方法实现模拟登陆。

如果大家对此不熟悉,可以参见

Urllib的基本使用

这样,登录后的结果就会保存在result变量中,我们只需要从result中提取出我们需要的数据就可以了。

乘胜追击

接下来,我们就分析一下数据啦,结果有这么几种:

1.登录成功 2.已经登录 3.用户不存在 4.密码错误 5.未知错误

好,利用result分析一下结果

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#打印登录结果
    def getLoginResult(self, result):
        if u"用户上线成功" in result:
            print self.getCurrentTime(),u"用户上线成功,在线时长为",self.overtime/60,"分钟"
        elif u"您已经建立了连接" in result:
            print self.getCurrentTime(),u"您已经建立了连接,无需重复登陆"
        elif u"用户不存在" in result:
            print self.getCurrentTime(),u"用户不存在,请检查学号是否正确"
        elif u"用户密码错误" in result:
            pattern = re.compile('<td class="tWhite">.*?2553:(.*?)</b>.*?</td>', re.S)
            res = re.search(pattern, result)
            if res:
                print self.getCurrentTime(),res.group(1),u"请重新修改密码"
        else:
            print self.getCurrentTime(),u"未知错误,请检查学号密码是否正确"

通过字符串匹配和正则表达式,我们分辨并提取出了上述五种情况。

增加循环检测 既然是检测网络是否断开,那么我们只需要每隔一段时间检测一下就好了,那就10秒吧。

因为这个10秒是可配置的,为了方便配置,统一配置到__init__方法里面。

 
1
2
#检测间隔时间,单位为秒
self.every = 10

然后,我们写一个循环来检测一下

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
while True:
            nowIP = self.getIP()
            if not nowIP:
                print self.getCurrentTime(), u"请检查是否正常连接QLSC_STU无线网络"
            else:
                print self.getCurrentTime(),u"成功连接了QLSC_STU网络,本机IP为",nowIP
                self.login()
                while True:
                    can_connect = self.canConnect()
                    if not can_connect:
                        nowIP = self.getIP()
                        if not nowIP:
                            print self.getCurrentTime(), u"当前已经断线,请确保连接上了QLSC_STU网络"
                        else:
                            print self.getCurrentTime(), u"当前已经断线,正在尝试重新连接"
                            self.login()
                    else:
                        print self.getCurrentTime(), u"当前网络连接正常"
                    time.sleep(self.every)
            time.sleep(self.every)

其中我们用到了canConnect方法,这个就是检测网络是否已经断开的方法,我们可以利用ping百度的方法来检测一下。

方法实现如下

 
1
2
3
4
5
6
7
8
9
#判断当前是否可以联网
    def canConnect(self):
        fnull = open(os.devnull, 'w')
        result = subprocess.call('ping www.baidu.com', shell = True, stdout = fnull, stderr = fnull)
        fnull.close()
        if result:
            return False
        else:
            return True

好啦,所有的要点我们已经逐一击破,等着凯旋吧

收拾战场

好了,所有的代码要点已经被我们攻破了,接下来就整理一下,让他们组合起来,变成一个应用程序吧。

 
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
__author__ = 'CQC'
#-*- coding:utf-8 -*-
 
import urllib
import urllib2
import socket
import types
import time
import re
import os
import subprocess
 
class Login:
 
    #初始化
    def __init__(self):
        #学号密码
        self.username = '201200131012'
        self.password = 'XXXXXX'
        #山大无线STU的IP网段
        self.ip_pre = '211.87'
        #登录时长
        self.overtime = 720
        #检测间隔时间,单位为秒
        self.every = 10
 
    #模拟登录
    def login(self):
        print self.getCurrentTime(), u"正在尝试认证QLSC_STU无线网络"
        ip = self.getIP()
        data = {
            "username": self.username,
            "password": self.password,
            "serverType": "",
            "isSavePass": "on",
            "Submit1": "",
            "Language": "Chinese",
            "ClientIP": self.getIP(),
            "timeoutvalue": 45,
            "heartbeat": 240,
            "fastwebornot": False,
            "StartTime": self.getNowTime(),
            #持续时间,超过这个时间自动掉线,可进行设置
            "shkOvertime": self.overtime,
            "strOSName": "",
            "iAdptIndex": "",
            "strAdptName": "",
            "strAdptStdName": "",
            "strFileEncoding": "",
            "PhysAddr": "",
            "bDHCPEnabled": "",
            "strIPAddrArray": "",
            "strMaskArray": "",
            "strMask": "",
            "iDHCPDelayTime": "",
            "iDHCPTryTimes": "",
            "strOldPrivateIP": self.getIP(),
            "strOldPublicIP": self.getIP(),
            "strPrivateIP": self.getIP(),
            "PublicIP": self.getIP(),
            "iIPCONFIG":0,
            "sHttpPrefix": "http://192.168.8.10",
            "title": "CAMS Portal"
        }
        #消息头
        headers = {
            'User-Agent' : 'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36',
            'Host': '192.168.8.10',
            'Origin': 'http://192.168.8.10',
            'Referer': 'http://192.168.8.10/portal/index_default.jsp?Language=Chinese'
        }
        post_data = urllib.urlencode(data)
        login_url = "http://192.168.8.10/portal/login.jsp?Flag=0"
        request = urllib2.Request(login_url, post_data, headers)
        response = urllib2.urlopen(request)
        result = response.read().decode('gbk')
        self.getLoginResult(result)
 
 
    #打印登录结果
    def getLoginResult(self, result):
        if u"用户上线成功" in result:
            print self.getCurrentTime(),u"用户上线成功,在线时长为",self.overtime/60,"分钟"
        elif u"您已经建立了连接" in result:
            print self.getCurrentTime(),u"您已经建立了连接,无需重复登陆"
        elif u"用户不存在" in result:
            print self.getCurrentTime(),u"用户不存在,请检查学号是否正确"
        elif u"用户密码错误" in result:
            pattern = re.compile('<td class="tWhite">.*?2553:(.*?)</b>.*?</td>', re.S)
            res = re.search(pattern, result)
            if res:
                print self.getCurrentTime(),res.group(1),u"请重新修改密码"
        else:
            print self.getCurrentTime(),u"未知错误,请检查学号密码是否正确"
 
    #获取当前时间戳,13位
    def getNowTime(self):
        return str(int(time.time()))+"000"
 
    #获取本机无线IP
    def getIP(self):
        local_iP = socket.gethostbyname(socket.gethostname())
        if self.ip_pre in str(local_iP):
            return str(local_iP)
        ip_lists = socket.gethostbyname_ex(socket.gethostname())
 
        for ip_list in ip_lists:
            if isinstance(ip_list, list):
                for i in ip_list:
                    if self.ip_pre in str(i):
                        return str(i)
            elif type(ip_list) is types.StringType:
                if self.ip_pre in ip_list:
                    return ip_list
 
    #判断当前是否可以联网
    def canConnect(self):
        fnull = open(os.devnull, 'w')
        result = subprocess.call('ping www.baidu.com', shell = True, stdout = fnull, stderr = fnull)
        fnull.close()
        if result:
            return False
        else:
            return True
 
    #获取当前时间
    def getCurrentTime(self):
        return time.strftime('[%Y-%m-%d %H:%M:%S]',time.localtime(time.time()))
 
    #主函数
    def main(self):
        print self.getCurrentTime(), u"您好,欢迎使用模拟登陆系统"
        while True:
            nowIP = self.getIP()
            if not nowIP:
                print self.getCurrentTime(), u"请检查是否正常连接QLSC_STU无线网络"
            else:
                print self.getCurrentTime(),u"成功连接了QLSC_STU网络,本机IP为",nowIP
                self.login()
                while True:
                    can_connect = self.canConnect()
                    if not can_connect:
                        nowIP = self.getIP()
                        if not nowIP:
                            print self.getCurrentTime(), u"当前已经掉线,请确保连接上了QLSC_STU网络"
                        else:
                            print self.getCurrentTime(), u"当前已经掉线,正在尝试重新连接"
                            self.login()
                    else:
                        print self.getCurrentTime(), u"当前网络连接正常"
                    time.sleep(self.every)
            time.sleep(self.every)
 
login = Login()
login.main()

来,我们来运行一下,看下效果吧! 执行

 
1
python login.py

当前是可以联网的,我分别在网页上操作执行了断开,操作,程序自动检测到掉线,自动重新连接。

接下来我直接断开了QLSC_STU网络的链接,程序同样检测到QLSC_STU这个热点没有连接上,提示用户链接。

接下来我重新连接上了这个热点,由于刚才已经登录上线,且持续时间较短,网络自动恢复正常。

下面是运行结果:

嗯,这样我们就是实现了自动掉线的检测和模拟登录。

凯旋而归

咿呀伊尔哟,想约妹子上自习吗?那就赶紧来试试吧!一网在手,天下我有!追男神女神都不再是梦想!

如果有问题,欢迎留言讨论,代码肯定有不完善的地方,仅供参考。

转载:静觅 » Python爬虫实战三之实现山东大学无线网络掉线自动重连

Python爬虫实战三之实现山东大学无线网络掉线自动重连的更多相关文章

  1. Python爬虫实战三之爬取嗅事百科段子

    一.前言 俗话说,上班时间是公司的,下班了时间才是自己的.搞点事情,写个爬虫程序,每天定期爬取点段子,看着自己爬的段子,也是一种乐趣. 二.Python爬取嗅事百科段子 1.确定爬取的目标网页 首先我 ...

  2. 路飞学城—Python爬虫实战密训班 第三章

    路飞学城—Python爬虫实战密训班 第三章 一.scrapy-redis插件实现简单分布式爬虫 scrapy-redis插件用于将scrapy和redis结合实现简单分布式爬虫: - 定义调度器 - ...

  3. Python爬虫实战---抓取图书馆借阅信息

    Python爬虫实战---抓取图书馆借阅信息 原创作品,引用请表明出处:Python爬虫实战---抓取图书馆借阅信息 前段时间在图书馆借了很多书,借得多了就容易忘记每本书的应还日期,老是担心自己会违约 ...

  4. Python爬虫实战七之计算大学本学期绩点

    大家好,本次为大家带来的项目是计算大学本学期绩点.首先说明的是,博主来自山东大学,有属于个人的学生成绩管理系统,需要学号密码才可以登录,不过可能广大读者没有这个学号密码,不能实际进行操作,所以最主要的 ...

  5. Python爬虫实战八之利用Selenium抓取淘宝匿名旺旺

    更新 其实本文的初衷是为了获取淘宝的非匿名旺旺,在淘宝详情页的最下方有相关评论,含有非匿名旺旺号,快一年了淘宝都没有修复这个. 可就在今天,淘宝把所有的账号设置成了匿名显示,SO,获取非匿名旺旺号已经 ...

  6. Python爬虫实战五之模拟登录淘宝并获取所有订单

    经过多次尝试,模拟登录淘宝终于成功了,实在是不容易,淘宝的登录加密和验证太复杂了,煞费苦心,在此写出来和大家一起分享,希望大家支持. 温馨提示 更新时间,2016-02-01,现在淘宝换成了滑块验证了 ...

  7. 转 Python爬虫实战一之爬取糗事百科段子

    静觅 » Python爬虫实战一之爬取糗事百科段子 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致 ...

  8. 路飞学城—Python爬虫实战密训班 第二章

    路飞学城—Python爬虫实战密训班 第二章 一.Selenium基础 Selenium是一个第三方模块,可以完全模拟用户在浏览器上操作(相当于在浏览器上点点点). 1.安装 - pip instal ...

  9. 《精通Python网络爬虫》|百度网盘免费下载|Python爬虫实战

    <精通Python网络爬虫>|百度网盘免费下载|Python爬虫实战 提取码:7wr5 内容简介 为什么写这本书 网络爬虫其实很早就出现了,最开始网络爬虫主要应用在各种搜索引擎中.在搜索引 ...

随机推荐

  1. 1-3 superset数据模型

    在models.py中大部分的class对应数据库中的表,那么我们就从AuditMixinNullable这个类开始我们的模型解析. AuditMixin:这个类是FAB(Flask  AppBuil ...

  2. clientHeight , scrollHeight , offsetHeight之间的区别及兼容方案

    clientHeight , scrollHeight , offsetHeight相信每个人都用过,可是每次用都要查一下到底哪个是文档大小哪个是视口大小,还有头疼的兼容问题. 先来官方的了解一下这三 ...

  3. JDK之集合乱序源码分析

    在JAVA的JDK中Collections类提供了shuffle方法用来对给定的集合参数进行乱序重排,之前面试也被问到过类似的问题,看了一下JDK的源码实现做个记录 1. 方法签名: Collecti ...

  4. Python GUI编程(Tkinter) windows界面开发

    Python实现GUI简单的来说可以调用Tkinter库,这样一般的需求都可以实现,显示简单的windows窗口代码如下: python_gui.py 1 #!C:\Python27\python.e ...

  5. Web页面获取用户控件页面中服务器控件的值

    用户控件页面后台: public string P_Name{get { return txt_P_name.Value; }set { txt_P_name.Value = value; }} We ...

  6. 快速安装laravel和依赖

    http://pkg.phpcomposer.com CMD敲命令: composer config -g repositories.packagist composer http://packagi ...

  7. dt转实体

    public class DtConvertToList<T> where T : new() { /// <summary> /// 实体转换辅助类 /// </sum ...

  8. [OpenCV Qt教程] 如何在内存中压缩图像

    本文译自:http://www.robot-home.it/blog/en/software/tutorial-opencv-qt-comprimere-un-immagine-in-memoria/ ...

  9. Jmeter如何监控服务器性能

    1.jmeter只需要安装一些插件 ,就可以像loadrunner一样监控服务器CPU.内存等性能参数 1.下载需要的jmeter插件      如图上面两个是jmeter插件,可以再下面的链接中下载 ...

  10. CentOS7.6安装稳定版Nginx

    官网地址:http://nginx.org/en/linux_packages.html#RHEL-CentOS 需先安装依赖:sudo yum install -y yum-utils 安装开始: ...