近期广州的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会自动将.pyw和pythonw进行关联,这样启动的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()
bat批处理文件
@echo off
echo starting auto_connect script
start auto_connect.pyw
exit