背景介绍
有些时候,想在手机上使用远程操作软件看看办公室电脑,但是发现办公室电脑没有连接上校园网,不能使用网络。故弄了一个小程序,设定时间自动登录校园网。
思路
使用selenium库来实现打开校园网网页,并在指定位置输入账号密码登录。
考虑到要使用selenium库需要预先下载浏览器驱动,并放到指定位置,这一操作对其他使用者不友好,故使用界面操作指定安装位置,自动下载驱动(使用的Edge浏览器)。
使用Python自带的库Tkinter来编写界面,易于操作。
演示
此为使用中的界面,由于输入账号密码不便展示,导致最后登录未成功。下面状态信息会提示未能登录。展示的给定位置已经有浏览器驱动文件,若没有,会提示没有并从网页上下载。
selenium库的使用。
这是使用selenium库编写的登录校园网的部分的函数。
def OpenWeb():
options = webdriver.EdgeOptions()
driver_path = str(path.get())+r'\msedgedriver.exe'
browser = webdriver.Edge(driver_path, options = options)
#指定驱动路径启动,无需将驱动装在指定位置。
browser.get("http://")#这个括号内是网页地址。
time.sleep(2)
a=UserMessage()[2]
b=UserMessage()[3]
try:
name = browser.find_element('xpath',r'//*[@id="edit_body"]/div[2]/div[1]/div/div[2]/div[1]/div/form/input[2]')
OutTips('\n 找到账号框,正在输入账号...')#这是一个在界面上显示的函数,可删除。
name.send_keys(a)
time.sleep(2)
passwd = browser.find_element('xpath',r'//*[@id="edit_body"]/div[2]/div[1]/div/div[2]/div[1]/div/form/input[3]')#这些是网页内指定内容的xpath
OutTips('\n 找到密码框,正在输入密码...')
passwd.send_keys(b)
time.sleep(2)
login_button = browser.find_element('xpath',r'//*[@id="edit_body"]/div[2]/div[1]/div/div[2]/div[1]/div/form/input[1]')
OutTips('\n 正在尝试登录...')
login_button.send_keys(Keys.ENTER)
time.sleep(5)
msge = browser.find_element('xpath',r'//*[@id="message"]')
somemsg = str(msge.text)[0:20]
noout = "请检查网络配置及确认账号及密码是否正确!"
if(somemsg==noout):
OutTips("\n 校园网出现错误,未能登录!")
except:
OutTips('\n 网页原因,未定位到指定元素。')
OutTips('\n 5s后关闭网页,等待下一次定时登录网页。')
time.sleep(5)
browser.quit()
Edge浏览器驱动下载安装部分。
这个是判断你装没装Edge浏览器,没装就给你装上,装上了的还会判断你装的版本对不对。这个代码段我是参考的 马拉多纳爱编程这位大佬的,原文地址:python/selenium中msedgedriver版本自动更新,解决“This version of MSEdgeDriver only supports MSEdge version 100“。在大佬基础上,我仅仅添加了安装地址的灵活获取。
class UpdateEdge:
#更新文件
def __init__(self, src_dir):
self.src_dir = src_dir
def update_edge(self):
if os.path.isfile(self.src_dir+'msedgedriver.exe'):
# 查看是否有msedgedriver.exe文件
time.sleep(2)
OutTips("\n "+str(self.src_dir)+"路径下已经存在msedgedriver.exe文件")
pass
else:
time.sleep(2)
OutTips("\n 未找到浏览器驱动文件。即将自动下载驱动并安装。")
time.sleep(2)
OutTips("\n 正在获取浏览器版本号...")
dom = xml.dom.minidom.parse(r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge'
r'.VisualElementsManifest.xml')
# 读取edge文件夹下面的xml文件(包含版本信息)
dom_ele = dom.documentElement
ve = dom_ele.getElementsByTagName('VisualElements')
ve_text = ve[0].toxml()
# 包含版本号的字符串文本
rematch = re.match(r'(.*)\"(.*)\\VisualElements\\Logo.png', ve_text)
edge_version = rematch.group(2)
time.sleep(2)
OutTips("\n 浏览器版本为:"+str(edge_version))
# 匹配得到版本号
time.sleep(2)
OutTips("\n 正在下载浏览器驱动压缩包...")
url = 'https://msedgedriver.azureedge.net/'+edge_version+'/edgedriver_win64.zip'
response = requests.get(url=url)
# 请求edgedriver下载链接
file_dir = self.src_dir+edge_version+'edgedriver_win64.zip'
open(file_dir, 'wb').write(response.content)
# 下载edgedriver压缩包
time.sleep(2)
OutTips("\n 正在解压压缩包...")
unzip(file_dir, self.src_dir)
# 在下载目录下解压edgedriver压缩包
time.sleep(2)
OutTips("\n 正在删除多余压缩包...\nEdge浏览器驱动安装完毕!")
if os.path.isfile(file_dir):
os.remove(file_dir)
else:
pass
try:
options = Options()
options.add_argument('headless')
webdriver.Edge(options=options)
except SessionNotCreatedException as msg:
OutTips("\n找到浏览器驱动文件,但是版本不对。")
reg = re.search("(.*)Current browser version is (.*) with", str(msg)) # 识别并匹配Exception信息中出现的版本号
edge_version = reg.group(2) # 获得版本号
OutTips("\n当前浏览器版本为:"+str(edge_version))
url = 'https://msedgedriver.azureedge.net/'+edge_version+'/edgedriver_win64.zip'
response = requests.get(url=url)
file_dir = self.src_dir+edge_version+'.zip'
open(file_dir, 'wb').write(response.content) # 下载压缩文件
unzip(file_dir, self.src_dir) # 解压文件
OutTips("\n重新下载安装完成!!!")
if os.path.isfile(file_dir):
OutTips("已删除多余的压缩文件。")
os.remove(file_dir) # 将多余的压缩文件删除
else:
pass
pass
def StartUpdate():
source_dir = str(path.get())+r'\\'
up = UpdateEdge(source_dir)
up.update_edge()
Tkinter界面设计部分。
其中解决了打包后左上角图标无法显示的问题。(对程序影响不大,强迫症想改图标可自行搜索,地址为:Pyinstaller 打包 Tkinter 程序时引入图标解决方法_lion_cui的博客)。
#建立主窗口
window = tk.Tk()
window.title('自动登录校园网小程序')
#设置窗口大小及位置
sw = window.winfo_screenwidth()#得到屏幕宽度
sh = window.winfo_screenheight()#得到屏幕高度
ww = 500
wh = 900#设置窗口宽高
x = (sw-ww) / 2
y = (sh-wh) / 3
window.geometry("%dx%d+%d+%d" %(ww,wh,x,y))#设置窗口大小,居中于屏幕
window.resizable(0,0) #防止用户调整尺寸
#此处缺少了图片的二进制代码
#tmp=open("tmp.ico","wb+")
#tmp.write(base64.b64decode(namepic))
#tmp.close()
#window.iconbitmap("tmp.ico")#设置窗口标签图片
#os.remove("tmp.ico")
#建立第一层框架:标题
frameUp = tk.Frame(window)
frameUp.pack()
#设置标题标签
title = tk.Label(frameUp , text="定时登录校园网小程序",
width=20,pady=30,
font=("微软雅黑",30,"bold") , fg="green")
title.grid(row=0, column=0, columnspan=10)
#建立第二层框架
frameMid = tk.Frame(window)
frameMid.pack()
#设置定时:标签+两个时间输入框
SetTimeName = tk.Label(frameMid, text="请输入登录时间:",
font=("微软雅黑",15,"bold"))
SetTimeName.grid(row=1, column=1,
pady=10,sticky="e")
HourInput = tk.Entry(frameMid, width=7)
HourInput.grid(row=1, column=2,
pady=10,sticky="n"+"s"+"w"+"e")
SetTimeHour = tk.Label(frameMid, text=":",
font=("微软雅黑",15,"bold"))
SetTimeHour.grid(row=1, column=3,
pady=10)
MinuteInput = tk.Entry(frameMid, width=7)
MinuteInput.grid(row=1, column=4,
pady=10,sticky="n"+"s"+"w"+"e")
HourInput.insert(0,(ReadFile()[0]))
MinuteInput.insert(0,(ReadFile()[1]))
#设置输入账号
Number = tk.Label(frameMid, text="请输入校园网账号:",
font=("微软雅黑",15,"bold"))
Number.grid(row=2, column=1,
pady=10,sticky="e")
NumberInput = tk.Entry(frameMid)
NumberInput.grid(row=2, column=2, columnspan=4,
pady=10,sticky="n"+"s"+"w"+"e")
NumberInput.insert(0,(ReadFile()[2]))
#设置输入密码
Key = tk.Label(frameMid, text="请输入校园网密码:",
font=("微软雅黑",15,"bold"))
Key.grid(row=3, column=1,
pady=10,sticky="e")
KeyInput = tk.Entry(frameMid)
KeyInput.grid(row=3, column=2, columnspan=4,
pady=10,sticky="n"+"s"+"w"+"e")
KeyInput.insert(0,(ReadFile()[3]))
#设置输入浏览器驱动器安装位置
Where = tk.Label(frameMid, text="请输入浏览器驱动安装位置:",
font=("微软雅黑",15,"bold"))
Where.grid(row=4, column=1,
pady=10,sticky="e")
path = tk.StringVar()
WhereInput = tk.Entry(frameMid,textvariable = path)
WhereInput.grid(row=4, column=2, columnspan=4,
pady=10,sticky="n"+"s"+"w"+"e")
openFile = tk.Button(frameMid, text="...",
font=("微软雅黑",15,"bold"),fg="blue",
bg="lightgray", relief="groove",
command=selectPath)
openFile.grid(row=4, column=7,
padx=10,pady=10)
WhereInput.insert(0,(ReadFile()[4]))
#建立第三层框架
frameThird = tk.Frame(window)
frameThird.pack()
#启动按钮+退出按钮
SaveAndStart = tk.Button(frameThird, text="保存并启动",
command=Start_Run,
font=("微软雅黑",20,"bold"),fg="darkorange",
bg="lightgray", relief="groove")
SaveAndStart.grid(row=0, column=0,
padx=10,pady=10,sticky="n"+"s"+"w"+"e")
QuitWin = tk.Button(frameThird, text="退出小程序",
command=window.quit,
font=("微软雅黑",20,"bold"),fg="darkorange",
bg="lightgray", relief="groove")
QuitWin.grid(row=0, column=1,
padx=10,pady=10,sticky="n"+"s"+"w"+"e")
#建立底层框架
frameBot = tk.Frame(window)
frameBot.pack()
tips = tk.Label(frameBot, text="状态信息:",
font=("微软雅黑",15,'bold'))
tips.grid(row=0, column=0,
padx=10,pady=5,sticky="w")
text = tk.Text(frameBot,
font=("楷体",15),
bg="lightgray",relief="groove",
width=45,height=20)
text.grid(row=1, column=0,
padx=0,pady=1)
#text.configure(state='disabled') # 设置Text文本框为 “不能编辑”
text.insert("end",ReadFile()[5])
text.insert("end",ReadFile()[6])
window.mainloop()#循环保持界面显示
程序的打包。
我使用的是pipenv创建虚拟环境,在虚拟环境中安装.py文件所用到的库,而不是所有的库,这样打包后会小一些。具体步骤如下:
在待打包文件夹下,shift+鼠标右键,点击”在此处PowerShell窗口“,然后输入以下创建虚拟环境(前提是需要下载pipenv库:pip install pipenv才能使用):
pipenv install
进入虚拟环境:
pipenv shell
安装需要的模块:
pip install ...#省略号为添加需要的库
#可用pipenv graph查看安装了那些库,以及关系
安装pyinstaller模块,用来打包。
pip install pyinstaller
打包文件,设置方法。
pyinstaller -Fw xxx.py -i logo.ico
#-F 参数为 产生单个的可执行文件
#-w 参数为 指定程序运行时不显示命令行窗口
#-i 参数为 设置打包程序的图标。格式为.ico。
ico图片最好是设置成多种大小以适应各种环境的显示,这个网站可以转换https://www.aconvert.com/icon/。
总结
第一次写,还有很多问题,请大家指出来,谢谢。原代码下载地址:定时自动登录校园网小程序-小程序文档类资源-CSDN文库,设置的0积分,欢迎下载。