注意:这篇文章上次更新于1072天前,文章内容可能已经过时。
需求分析
emm… 怎么说呢,日常使用电脑你肯定不需要自动登录校园网,但是在某些特殊情况下,如果你的主机与互联网断开了连接,而你又无法在现场操作主机登录校园网,那通常意味着生产力的下降,科研进度的延误等等后果…
前两周由于疫情原因学校关闭了实验室,志成哥在寝室用笔记本登录了一下校园网,就挤掉了实验室的服务器网络,导致无法使用向日葵进行远程连接。只能选择挨门卫大爷一顿骂然后去实验室重新登录校园网。如果当时志成哥的服务器上运行了自动登录校园网的定时任务,就可以免于这一顿挨骂了😂。
试想一下,如果寒假在家期间想要使用实验室的主机进行工作,但是却因为学校的网络中心抽风进行升级维护,导致主机与互联网断开连接,那可就不是挨一顿骂就能解决的了。
寒假即将到来,为了避免上述尴尬局面的发生,故提前完成这一需求。
思路
网上查了一下校园网的自动登录脚本,大多是通过 requests 包模拟网络请求实现的。鉴于本人学习能力比较差,看了好多博客也不知道到底该怎么实现,最主要的原因是不明白网络通信的具体过程,每个参数都是干什么用的,比如说 cookie 等等,所以也写不出来相应的代码。
但是,正所谓条条大路通罗马,实现一个自动登录的需求,又何必局限于 requests 包呢,本文使用 RPA-Python 来实现这一功能,使用这个包不需要了解网络通信过程,只需要你拥有基本的英语阅读能力或者翻译软件的使用能力,了解相关接口的使用方法即可。
这个包的功能大概可以描述为使用代码控制你的电脑。我们需要使用这个包完成 打开浏览器 ==> 输入登录地址 ==> 输入学号,密码 ==> 点击回车 这一系列操作。
最后,在 Windows 平台上,将我们写好的代码打包成 exe 可执行文件,创建定时任务,让该程序每天都自动执行一遍;在 Linux 平台上,不需要打包过程,直接创建定时任务执行 python 脚本即可。
实现
这里记录一下在 Windows 平台上 RPA-Python 的使用示例。
脚本编写
首先需要获取校园网的登录地址,我们在没有登录校园网的情况下请求一下百度的地址。
可以看到我们获得的请求结果是一段 js 脚本,这个脚本给我们重定向到了一个新的地址,这个新地址指向了我们平时使用的校园网的登录认证界面。
import requests
def auto_login():
data = requests.get("http://www.baidu.com")
print(data.text)
if __name__ == "__main__":
auto_login()
上面的网址就是我们登录认证的地址了,嗯… ,我也不知道这个地址里包含了什么信息,为了防止它是动态的,还是不要在脚本里把这个 url 写死了。可以通过简单的字符串分割来获得 url。
def auto_login():
data = requests.get("http://www.baidu.com")
_, url, _ = data.text.split("'")
print(url)
接下来我们就可以使用 RPA-Python 来进行自动操作了。具体的使用方法可以参考官方仓库。
其中需要注意的是,第一次使用该模块的 init 函数时会从 GitHub 进行下载,需要你保持一个通畅的网络连接。
先给出示例代码,再进行简单解释。
import requests
import rpa as r
id = '' # 这里输入学号
pwd = '' # 这里输入密码
def auto_login():
data = requests.get("http://www.baidu.com")
try:
_, url, _ = data.text.split("'")
except:
url = 'http://202.118.88.9/eportal/index.jsp?wlanuserip=1db427551d9861d328753abeaf69e2a1&wlanacname=c20f646d18ec8420743bb59779d3aa5d&ssid=&nasip=321b8c06ed4b01461a74c22a11633718&snmpagentip=&mac=27aa970db3d666f7a1dcc45862e8c0a5&t=wireless-v2&url=137959cd1821ef100482212731b93e78da05ff2641772a02&apmac=&nasid=c20f646d18ec8420743bb59779d3aa5d&vid=37abe54c3683fd75&port=c87f0377ae0b584a&nasportid=689587e344e622f6867192a09cc4ec23e7771c5f290d48554f610793f1fadcacd78df25078f00bf30d5f119b8706fd34'
# print(url)
r.init(chrome_browser = True, headless_mode = False) # 第一次初始化,需要你的网络可以稳定的与 GitHub 进行通信,这里需要从 GitHub下载文件
# r.init(chrome_browser = True, headless_mode = True) # 如果上面的代码可以正确执行,那么以后可以使用这种模式进行初始化
r.url(url) # url函数会调用 Chrome 浏览器,并且访问我们传入的参数。
r.type('//*[@name="username"]','[clear]' + id) # type 函数的第一个参数是一个元素选择器,这里我们选择的是,具有属性 name 并且其值是 username 的元素,这实际上是网页的一个 input标签。
r.type('//*[@type="password"]', pwd+'[enter]') # type 函数的第二个参数是我们要输入的内容,如果字符串中包含 [enter] 将会在输入结束后按下回车键。
r.close()
exit(0)
if __name__ == "__main__":
auto_login()
执行上面的代码,就会自动完成 打开浏览器 ==> 输入登录地址 ==> 输入学号,密码 ==> 点击回车 这一些列操作,效果如下图。
下面说明几个我踩过的坑以及注意事项。
-
关于 r.init() 函数。这个函数设置 chrome_browser = True 浏览器为 True 的模式会调用 Chrome 浏览器,因此,这个脚本的运行是依赖于 Chrome 的。第二个参数 headless_mode = False,表明不使用 Chrome 浏览器的 headless 模式。那么什么是 headless 模式呢?建议自行百度。我的理解是,headless 模式决定了是否进行界面的渲染,要知道通信的过程主要是编码后的信息进行交换,是否进行界面渲染,是不影响通信的顺利完成的,因此,在实际使用过程中建议使用 headless 模式,也就是说:将 init 函数的 headless_mode 参数指定为 True,虽然不会显式调用 Chrome进行界面渲染,后面的工作还是可以顺利完成的。至于为什么建议设置 headless_mode = True ,可以参考:https://github.com/tebelorg/RPA-Python/issues/309,我在第二次运行脚本时似乎也遇到了这个问题。
-
type 函数的第一个参数时元素选择器,具体使用方法建议参考官方仓库。本案例中使用两个 input 标签的 name 和 type 属性来进行定位,你也可以使用其他属性。
Windows 定时任务
我们首先使用 pyinstaller 将 Python 脚本封装成可执行文件。
在终端执行:
pyinstaller -F main.py
编译完成后,可以在项目目录下找到 main.exe 文件。
运行这个可执行文件,会在该目录下生成一个 rpa_python.log 文件,打开这个文件,如果是如下内容,代表执行成功。
在正确执行的前提下可以设置 Windows 定时任务了。
首先,右键点击此电脑,点击管理,选择任务计划程序,点击创建任务。
填写名称。
点击触发器,点击新建,下图只是一个示例,具体情况根据自己的需要进行修改。
点击操作选项卡,点击新建,填写刚刚生成的可执行文件的位置,起始于填写这个文件的所在目录。
条件和设置选项卡可以根据需要进行调整。最后点击确定,要求我们输入密码。
可以在任务计划程序库中看到详细信息。
可执行文件 main.exe 目录下的 rpa_python.log 的修改日期与定时任务时间一致,代表执行成功。
保险起见,各位也可以断网进行测试,看能否自动联网。
上述操作中的触发器我设置的一次,用来验证能否正确执行,如果可以正确执行,就可以把该项设置为 每天 了。
Ubuntu 上可以使用 corntab 来定时执行 Python 脚本文件。我没有 Ubuntu 系统,就不做演示了。
最后,RPA-Python 这个项目简单易用,应该还可以玩很多骚操作,欢迎有想法的友友们留言。🧐