校园网掉线自动重连小助手--Python

一背景

PC在连接学校校园网的情况下如果持续一段时间未使用足够多的流量则会掉线,严重影响了电脑不在身边时通过向日葵远程的访问.因此特地写了一个校园网自动重连的小助手.

二获取数据包

连接校园网,进入认证界面,如下图
校园网掉线自动重连小助手--Python_第1张图片
按F12,点击Network和Preserve log准备抓包
校园网掉线自动重连小助手--Python_第2张图片
输入账号密码,点击登录,此时会出现一大堆数据包,一般选择第一个校园网掉线自动重连小助手--Python_第3张图片
下图中的就是我们写代码时需要用到的数据
校园网掉线自动重连小助手--Python_第4张图片
在这里插入图片描述

编写自动重连脚本(附带日志)

思路: 每隔60s ping一次百度,如果未ping通则断掉当前WIFI(我所在学校每天凌晨2点左右会断网,如果不进行重新连接就算认证成功也没有网),再连接校园网并认证.

Ping www.baidu.com判断当前网络是否可以上网

    def Ping(self):
        iplist = list()
        ip = 'www.baidu.com'
        # 这里使用subprocess模块而不使用os模块,因为os模块在打包后执行cmd命令会出现黑色命令框
        backinfo = subprocess.call('ping www.baidu.com -n 1', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # print(backinfo)
        if backinfo:
            print('no')
            self.connectFlag = 0
            logging.info('网络未连接')
        else:
            iplist.append(ip)
            self.connectFlag = 1

断开当前网络

    def disconnect(self):  # 断开wifi
     	# 这里使用subprocess模块而不使用os模块,因为os模块在打包后执行cmd命令会出现黑色命令框
        subprocess.call("netsh wlan disconnect", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

连接校园网

    def connect_wifi(self, name=None):  # 连接wifi
        # 这里使用subprocess模块而不使用os模块,因为os模块在打包后执行cmd命令会出现黑色命令框
        cmd = "netsh wlan connect name=" + str(name)
        subprocess.call(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

自动认证(因为方便后期用户的使用,创建了一个.json的配置文件,通过读字典的方式来获取不同的用户信息)

   def connect(self):  # 自动认证
        myaddr = self.getlocalIP()
        userId = self.data["userId"]  # 用户名
        password = self.data["password"]  # 密码
        service = self.data["service"]
        queryString = "wlanacname%3DAC6805%26nasip%3D172.18.95.254%26wlanuserip%3D" + myaddr +"%26wlanparameter" \
                                                                                                  "%3D98%3A3b%3A8f" \
                                                                                                  "%3Abd%3A6b%3A72" \
                                                                                                  "%26url%3Dhttp%3A" \
                                                                                                  "%2F%2Fwww" \
                                                                                                  ".msftconnecttest" \
                                                                                                  ".com%2Fredirect" \
                                                                                                  "%26SSID%3DZJGM" \
                                                                                                  "-%25E5%25AD%25A6" \
                                                                                                  "%25E7%2594%259F "
        # 认证的ip地址
        post_addr = self.data["post_addr"]
        # 请求头
        post_header = {
            'Request URL': self.data["Request_URL"],
            'Request Method': self.data["Request_Method"],
            'Accept': self.data["Accept"],
            'Accept-Encoding': self.data["Accept_Encoding"],
            'Accept-Language': self.data["Accept_Language"],
            'Connection': self.data["Connection"],
            # 'Content-Length': '',
            'Content-Type': self.data["Content_Type"],
            'Host': self.data["Host"],
            'Origin': self.data["Origin"],
            'User-Agent': self.data["User_Agent"],
        }
        # 用户数据
        post_data = {
            'userId': userId,
            'password': password,
            'service': service,
            'queryString': queryString,
            'operatorPwd': "",
            'operatorUserId': "",
            'validcode': "",
            'passwordEncrypt': "",
        }
        # 发送post请求登录网页
        z = requests.post(post_addr, data=post_data, headers=post_header)
        z.raise_for_status()
        print("login success!")

读取配置文件

    def config(self):   # 读取config.json配置文件
        with open("config.json", "r", encoding='utf-8') as f:
            self.data = json.loads(f.read())

话不多说直接上源码(有点乱,请多多指教)

# -*- coding: utf-8 -*-
import os
import time
from threading import Timer
import requests
import json
import logging
import socket
import subprocess
import ssl


class Reconnect:
    def __init__(self):
        self.connectFlag = 0
        self.data = {}

    def config(self):   # 读取config.json配置文件
        with open("config.json", "r", encoding='utf-8') as f:
            self.data = json.loads(f.read())

    def log(self):
        logging.basicConfig(filename=os.path.join(os.getcwd(), 'log.txt'), level=logging.INFO,
                            format='%(asctime)s %(filename)s : %(levelname)s %(message)s',  # 定义输出log的格式
                            datefmt='%Y-%m-%d %A %H:%M:%S',
                            filemode='w')

    def getlocalIP(self):
        # 获取本机电脑名
        myname = socket.getfqdn(socket.gethostname())
        # 获取本机ip
        myaddr = socket.gethostbyname(myname)
        return myaddr

    def disconnect(self):  # 断开wifi
        #  os.system("netsh wlan disconnect")
        subprocess.call("netsh wlan disconnect", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    def connect_wifi(self, name=None):  # 连接wifi
        #  os.system("netsh wlan connect name=%s" % name)
        cmd = "netsh wlan connect name=" + str(name)
        subprocess.call(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    def Ping(self):
        iplist = list()
        ip = 'www.baidu.com'
        # backinfo = os.system('ping %s -n 1 -w 1' % ip)  # 实现pingIP地址的功能
        backinfo = subprocess.call('ping www.baidu.com -n 1', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        # print(backinfo)
        if backinfo:
            print('no')
            self.connectFlag = 0
            logging.info('网络未连接')
        else:
            iplist.append(ip)
            self.connectFlag = 1

        if self.connectFlag == 0:
            self.disconnect()
            self.connect_wifi(self.data["WifiName"])
            time.sleep(5)
            self.connect()  # 认证
            backinfo = subprocess.call('ping www.baidu.com -n 1',
                                       shell=True,
                                       stdin=subprocess.PIPE,
                                       stdout=subprocess.PIPE,
                                       stderr=subprocess.PIPE)
            # print(backinfo)
            if backinfo:
                logging.info('网络连接失败,请检查网络')
            else:
                logging.info('网络已连接')
        t = Timer(self.data["Ping_Interval"], self.Ping, ()).start()

    def timedPing(self):
        t = Timer(1, self.Ping, ()).start()  # 打开脚本1s后检测一次网络状态,随后60s检测一次

    def connect(self):  # 自动认证
        myaddr = self.getlocalIP()
        userId = self.data["userId"]  # 用户名
        password = self.data["password"]  # 密码
        service = self.data["service"]
        queryString = "wlanacname%3DAC6805%26nasip%3D172.18.95.254%26wlanuserip%3D" + myaddr +"%26wlanparameter" \
                                                                                                  "%3D98%3A3b%3A8f" \
                                                                                                  "%3Abd%3A6b%3A72" \
                                                                                                  "%26url%3Dhttp%3A" \
                                                                                                  "%2F%2Fwww" \
                                                                                                  ".msftconnecttest" \
                                                                                                  ".com%2Fredirect" \
                                                                                                  "%26SSID%3DZJGM" \
                                                                                                  "-%25E5%25AD%25A6" \
                                                                                                  "%25E7%2594%259F "
        # 认证的ip地址
        post_addr = self.data["post_addr"]
        # 请求头
        post_header = {
            'Request URL': self.data["Request_URL"],
            'Request Method': self.data["Request_Method"],
            'Accept': self.data["Accept"],
            'Accept-Encoding': self.data["Accept_Encoding"],
            'Accept-Language': self.data["Accept_Language"],
            'Connection': self.data["Connection"],
            # 'Content-Length': '',
            'Content-Type': self.data["Content_Type"],
            'Host': self.data["Host"],
            'Origin': self.data["Origin"],
            'User-Agent': self.data["User_Agent"],
        }
        # 用户数据
        post_data = {
            'userId': userId,
            'password': password,
            'service': service,
            'queryString': queryString,
            'operatorPwd': "",
            'operatorUserId': "",
            'validcode': "",
            'passwordEncrypt': "",
        }
        # 发送post请求登录网页
        z = requests.post(post_addr, data=post_data, headers=post_header)
        z.raise_for_status()
        print("login success!")


if __name__ == '__main__':
    reconnect = Reconnect()
    reconnect.config()
    reconnect.log()
    logging.info('用户信息配置成功!')
    reconnect.timedPing()

json配置文件(信息从上文的消息包中获得)

{
  "userId": "账号",
  "password": "密码",
  "WifiName": "校园网名",
  "Ping_Interval": 60,
  "service": "******",
  "queryString": "****",
  "post_addr": "*****",
  "Request_URL": "*****",
  "Request_Method": "POST",
  "Accept": "*/*",
  "Accept_Encoding": "*****",
  "Accept_Language": "*****",
  "Connection": "keep-alive",
  "Content_Type": "application/x-www-form-urlencoded; charset=UTF-8",
  "Host": "*****",
  "Origin": "*****",
  "User_Agent": "*****"

}

最后看一下成品
在这里插入图片描述
校园网掉线自动重连小助手--Python_第5张图片

你可能感兴趣的:(网络,python,wifi,http,经验分享)