• 记一次通过python脚本完成自动联网


    背景

    近期广州的yq比较严重,无奈本狗天选打工人,至今没有在家办公过。但是公司发了通知,说随时做好在家办公的准备。

    我原先是每天背着自己的笔记本上下班的,全程用笔记本办公。而最近双11,我换了台新的笔记本,原先的那台,在清除掉全部数据,格式化所有磁盘,重置系统后,已经被我卖二手处理掉了。新的笔记本我又只想自用,不想拿来办公。

    于是花了几天时间,在公司的台式电脑上完成了各种环境配置。后续准备用公司的台式电脑来办公。

    我打算将公司的台式机一直开着,并开启teamviewer,这样如果居家办公的话,我就在家里的笔记本上,用teamviewer远程连接到公司的台式机办公就好啦。

    但是公司的台式机只能插网线,并且需要完成登录认证,才能联网。并且每隔10多个小时,网络会断掉,需要重新进行登录认证。这样我如果长时间居家办公的话,网络一断掉,就无法连接到公司电脑进行办公了。

    于是我就想通过编程来实现网络的断线自动重连。

    开搞

    公司的上网认证比较麻烦,必须用IE浏览器,并且需要手动关掉SSL证书验证,输入账户名和密码,登录后方可完成认证。

    一开始我的想法是控制浏览器,通过模拟键盘输入,鼠标点击的方式,来用程序模拟人的操作。

    对于这种自动化需求,首选当然是python啦。

    于是我开始现学python,一通搜索后,准备利用python的selenium库来实现我的想法。

    随后在群里询问了一下群友,问有无优质的python快速上手资料时,一位群友得知我的想法后,说可以考虑直接模拟HTTP请求。

    对呀!为啥要搞的那么复杂!于是我在IE里打开上网认证页面,通过F12打开控制台,定位到点击登录按钮时触发的JS函数,打上断点进行跟踪,最后找到了请求参数的构造规则。

    然后现学现查python语法,将生成请求参数的JS函数,用python复现了一次。并进行几次认证登录,用Fiddler抓取HTTP包,将其中的参数搞出来,再用写好的python脚本进行验证,确认参数构造规则没问题后,学了下 python 中用来发HTTP请求的库,并编写HTTP请求的代码。

    然后发起HTTP请求尝试了下,可以成功联网。

    于是通过一个简单的HTTP请求就完成了联网操作。

    接下来就是一些完善工作。包括

    • 输出日志
    • 配置定时任务
    • 配置开机自启动

    其中

    • 输出日志
      可以直接用print函数,指定写入到某个文件即可,其中将flush置为true,可以实时刷到磁盘,即能实时看到输出的日志

    • 配置定时任务
      一开始考虑用windows自带的定时任务,随后发现windows自带的定时任务,最细的粒度只支持每天。即最多只能每隔24小时运行一次,这显然不符合我的需求。我希望是每1分钟就检查一次网络连接,若没网,则发起HTTP请求进行联网。这样如果公司台式机的网络断掉了,而我又在居家办公的话,最多只需要等1分钟,就能再次远程连接到公司电脑。
      所以,最后打算用python自带的定时任务库来实现,在查了资料并对比后,选择了schedule这个库,比较轻量和简单,上手快。

    • 开机启动
      最后就是考虑把这个python脚本做成开机自启动了,这样以来,我每天来公司上班,也不需要手动联网了。并且如果公司电脑重启后,也能再次启动这个脚本,这样就保证无论何时,电脑都能自动联网。
      我打算用bat脚本来启动这个python程序,这里我又跑去看了一下bat批处理的语法。结果发现搞的很麻烦。最终只用一行bat代码就完成python脚本的启动。
      另外,若在bat脚本中用命令python xxx.py来启动,则bat脚本的黑框窗口无法被关闭,无论使用exit命令,还是taskkill都无法关闭。最后发现,将python脚本的后缀,.py换成.pyw,然后通过bat命令start xxx.pyw 直接启动这个脚本,windows会自动将.pywpythonw进行关联,这样启动的python程序,会在后台运行,并且bat批处理运行完后,黑框会自动退出。

      编写好这个bat批处理文件后,再将这个bat文件添加到电脑的启动项即可。win + R 打开运行窗口,输入shell:startup打开启动项的目录,然后将这个bat批处理文件直接扔进去,或者优雅一点,针对这个bat生成一个快捷方式,将快捷方式扔进这个目录。然后把bat文件和python脚本统一放在另一个文件夹里做维护即可。
      至此,通过python脚本完成自动联网,整个功能实现完毕

    参考代码

    python代码

    # 文件名 auto_connect.pyw
    #import threading
    import os
    import schedule
    import datetime
    import time
    #import webbrowser
    import requests
    #from selenium import webdriver
    
    url = "https://xxxxx/login.php"
    username = "xxx" #用户名
    pw= "xxx" #密码
    #打开日志文件
    fp = open('auto_connect_log.txt', 'a+') # append模式写
    
    def getLatestDatetime():
        return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  
    
    # 获取毫秒级时间戳, 直接返回一个字符串
    def getTimestamp():
        return str(int(round(time.time() * 1000)))
        
    def print_to_file(msg):
        print(getLatestDatetime(), " ", msg)
        print(getLatestDatetime(), " ", msg, file = fp, flush = True) # flush = True 实时刷盘
        
    # 测试没问题了
    def hash(src, pwd):
        ans = ''
    	# 略
    	# 把生成请求参数的JS函数, 用python复现一遍
        return ans    
        
    
    def login():
        #webbrowser.open("http://www.baidu.com")
        timestamp = getTimestamp()
        param = {'opr':'pwdLogin', 'userName':username, 'pwd':hash(pw, timestamp), 'auth_tag':timestamp}
        response = requests.post(url, data = param, verify=False) #false表示不验证SSL证书
        print_to_file('status:'+str(response.status_code))
        print_to_file('response:'+str(response.text))
        
        
    def isConnected():
        try:
            html = requests.get("http://www.baidu.com", timeout = 2)
        except:
            return False
        return True
    
    def connectIfNeeded():
        print_to_file("检查网络状态...")
        if isConnected():
            print_to_file("网络已通")
        else:
            print_to_file("网络不通, 准备执行认证登录...")
            login()
    
    #测试定时任务
    def job():
        print_to_file("hello, world")
     
    # 开始执行定时任务, 每60s检查一次网络连接
    schedule.every(60).seconds.do(connectIfNeeded)
    while True:
        schedule.run_pending()
    
    
    
    • 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

    bat批处理文件

    @echo off
    echo starting auto_connect script
    start auto_connect.pyw 
    exit
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    将时间序列转成图像——递归图方法 Matlab实现
    【Java面试题】面试刷完高手回答,直接开挂回答!SimpleDateFormat 是线程安全的吗 为什么?
    Godot屏幕抖动效果原理与实现
    pacman 升级软件包提示 “failed to commit transaction (invalid or corrupted package)“
    飞行动力学 - 第32节-荷兰滚飞行品质 之 基础点摘要
    玩以太坊链上项目的必备技能(类型-值类型-Solidity之旅二)
    这个岗位年薪几十万,为何各大科技企业仍招不到人?
    UE5开发游戏Tutorial
    IDE如何统计代码总行数———————插件管理
    杭电oj 2043 密码 C语言
  • 原文地址:https://blog.csdn.net/vcj1009784814/article/details/127861306