Python实现校园网断开自动重连

背景

最近实验室服务器的校园网总是掉线,严重影响服务器的使用。网络上有基于锐捷客户端实现的MentoHUST工具,该工具可以在电脑上直接连接校园网正常实现自动重连,但是通过连接路由器转发网络时无法验证服务器。同样还有基于软路由实现的openwrt,但是这需要一台闲置的电脑作为软路由系统。因此特地基于校园网模拟登录写了一个实现校园网自动重连的Python脚本。

登录页面

通过分析发现校园网登录页面下,主要包含用户名、密码两个输入框已经登录连接按钮。通过分析源码,我们发现在输入密码前,真实密码输入框id="pwd"是隐藏的,需要鼠标点击id="pwd_tip"输入框后真实密码输入框才会显示出来。

<!--> 用户名输入框 <-->
<input class="input_tip" name="username_tip" id="username_tip" readonly="readonly" value="用户名" 
       style="font-size: 16px; color: rgba(0, 0, 0, 0.54); border: none; display: block;">
<!--> 密码输入前需点击该输入框 <-->
<input class="input_tip" name="pwd_tip" id="pwd_tip" readonly="readonly" value="密码" 
       style="font-size: 16px; color: rgba(0, 0, 0, 0.54); border: none; display: block;">
<!--> 密码输入框 <-->
<input name="pwd" class="input" id="pwd" type="password" 
	   style="border: none; display: none; float: left; width: 240px;" 
       tabindex="0" tipinfo="Password" value="">
<!--> 登录按钮 <-->
<div id="loginLink_div"></div>

编写代码

思路: 每隔10分钟ping一次百度,如果无法ping通则自动重新认证校园网。

  1. 配置log文件
import logging
logging.basicConfig(filename='./network_reconnect.log',
                    level=logging.INFO,  # 定义输出log的类型
                    format='%(asctime)s %(filename)s : %(levelname)s %(message)s',  # 定义输出log的格式
                    datefmt='%Y-%m-%d %A %H:%M:%S',
                    filemode='w')
  1. Ping网络判断当前网络是否可以上网(百度+校园网)
def ping_network(self, ip_or_domain):
    """
        Input: ip_or_domain, ip地址或者域名
        return: True or False, 网络连通性, True表示网络可连通
    """
    ping_cmd = 'ping %s -n 1' % ip_or_domain
    backinfo = subprocess.call(ping_cmd,
                               shell=True,
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)
    # 0: 网络可连通, 1: 网络不可达
    ret = True if backinfo == 0 else False
    return ret
  1. 重新连接校园网(采用webdriver+chromedriver模拟登录:首先下载chromedriver驱动,解压后将chromedriver.exe放在主程序文件夹下)
import time
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

def reconnect_network(self):
    campus_network_url = "http://192.168.50.3:8080/"  # 校园网登录页面
    chromedriver = "./chromedriver.exe"  # chromedriver.exe文件所在位置
    os.environ["webdriver.chrome.driver"] = chromedriver
    options = Options()
    # 取消DevTools listening on ws://127.0.0.1...提示
    options.add_experimental_option('excludeSwitches', ['enable-logging'])
    options.add_argument("--headless")                             # 以无窗口模式运行chromedriver程序
    browser = webdriver.Chrome(chromedriver, options=options)      # 模拟打开浏览器
    browser.get(campus_network_url)                                # 打开校园网登录页面
    browser.find_element_by_id("username").send_keys(self.userId)  # 输入账号
    time.sleep(1)
    browser.find_element_by_id("pwd_tip").click()                  # 点击登录显示隐藏密码输入框
    time.sleep(1)
    browser.find_element_by_id("pwd").send_keys(self.password)     # 输入密码
    time.sleep(1)
    browser.find_element_by_id("loginLink_div").click()            # 点击连接按钮
    time.sleep(2)
    reconnect_res = browser.title == "登录成功"
    browser.quit()
    return reconnect_res
  1. 每十分钟判断一次
def __call__(self):
    self.run_loop() # 第一次执行
    # 十分钟后判断是否需要重连
    schedule.every(10).minutes.do(self.run_loop)
    while True:
        schedule.run_pending()
  1. 循环判断主程序
def run_loop(self):
    ping_baidu = 'www.baidu.com'  # 百  度
    ping_campus = '192.168.50.3'  # 校园网
    if self.ping_network(ping_baidu):
      	print("校园网连接正常.")
      	# logging.info("校园网连接正常")
    else:
        print("校园网未登录, 尝试重连中...")
        logging.info("校园网未登录, 尝试重连中...")
        if self.ping_network(ping_campus):
            reconnect_res = self.reconnect_network()
        	if reconnect_res and self.ping_network(ping_baidu):
          		print("校园网已使用账户%s重新登录." % self.userId)
          		logging.info("校园网已使用账户%s重新登录." % self.userId)
        	else:
              print("校园网未登录成功, 请检查账号密码是否输入正确!")
              print("您输入的用户名是: %s 密码: %s" % (self.userId, self.password))
              logging.info("校园网未登录成功, 请检查账号密码是否输入正确!")
      	else:
        	print("无法访问校园网登录页面, 请检查是否连接网络!")

Windows bat脚本命令

每次需要运行python命令,比较麻烦,所以写了自动运行的Windows bat脚本。切换到connect_campus_network.py文件目录下(我的目录为E:\CampusNetwork),并运行python脚本:

::auto_connet_network.bat
start cmd /k "echo Check campus network connection:&&cd /d E:\CampusNetwork&&python connect_campus_network.py"