python3一键上网认证的图形化exe程序(上篇)

-------------------------------------------------

python 3.6

自带的IDLE

-------------------------------------------------

背景

自学python不到两个月,学完一遍基础以后发现又忘了差不多了,于是练习一下有趣的小项目巩固一下知识,这个程序从提出到完成初版用了大概2天半时间,遇到一些坑,但是都顺利解决了。一开始是做了专用版(专用版就是两个exe,其中的ip,账号和密码是手动写入的),因为想上传学校内网,就做了这个图形化界面的程序。大概功能是:1.可以手动输入账号和密码并保存。2.可以一键上线或下线(内部包括自动获取ip)。QAQ


分析

完成这个程序的部分:

1.完成一键上网的代码

2.完成一键下线的代码

3.自动获取计算机的ip地址

4.GUI界面

5.自写的使用说明

6.写程序过程中遇到的问题


1.完成一键上网的代码

用爬虫里的思路,先打开开发者选项的network,自行上网认证一次

然后选择post的请求,看请求标头,对比同学的,可以构建自己的请求标头(基本是一样的,其中Content-Length可能不一样,但是后开经过测试发现这个数据有无无伤大雅)。然后是观察post请求的正文的请求正文,与同学的对比后可以构建出需要传输的data,最后就可以用request.post来发送上网请求。(图懒得截了,具体类比下面的下线的截图)

一键上网代码:

# -*- coding:utf-8 -*-
import requests

#登录地址
post_addr="http://219.136.125.139/portalAuthAction.do"

#构造头部信息
my_headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',
    'Accept-Language': 'zh-CN',
    'Accept-Encoding': 'gzip, deflate',
    'Host':'219.136.125.139',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
    'Content-Length': '511',#这个不同甚至没有无伤大雅
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': 'JSESSIONID=19AE14CB4E83F1342FE36944A6609E86.worker4',
    'Referer': 'http://219.136.125.139/portalReceiveAction.do?wlanuserip=10.110.75.3&wlanacname=gzhlxy&wlanacip=183.56.17.19'
    }

#构造登录数据
post_data={
   'act': '',
   'auth_type': 'PAP',
   'authkey': 'gzhlxy',
   'bank_acct': '',
   'chal_id': '',
   'chal_vector': '',
   'domain': 'GDHLXY',
   'freepasswd': '',
   'freeuser': '',
   'getpasstype': '0',
   'is189': 'true',
   'isCookies': '',
   'isHaveNotice': '0',
   'isRadiusProxy': 'false',
   'listgetpass': '0',
   'listpasscode': '0',
   'listwxauth': '0',
   'logintype': '0',
   'mac': '',
   'message': '',
   'passwd': 'A05237638',#不同(密码)
   'randstr': '',
   'req_id': '',
   'seq_id': '',
   'smsid': '0',
   'ssid': '',
   'templatetype': '1',
   'terminalType': '',
   'times': '12',
   'tname': '5',
   'url': '',
   'userid': '1199605237638@GDHLXY',#不同
   'useridtemp': '1199605237638',#不同(账号)
   'usertime': '0',
   'usertype': '0',
   'version': '0',
   'vlan': '',
   'weizhi': '0',
   'wlanacIp': '183.56.17.19',
   'wlanacname': 'gzhlxy',
   'wlanuserip': '10.110.75.38'#不同
          }   
#发送post请求上网认证
z=requests.post(post_addr,data=post_data,headers=my_headers)



2.完成一键下线的代码

用相同的思路获取需要的信息,不一一赘述了。




一键下线代码:

# -*- coding:utf-8 -*-
import requests

#发送请求的地址
post_addr="http://219.136.125.139/portalDisconnAction.do"

#构造头部信息
my_headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
    'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',
    'Accept-Language': 'zh-CN',
    'Accept-Encoding': 'gzip, deflate',
    'Host':'219.136.125.139',
    'Connection': 'keep-alive',
    'Cache-Control': 'no-cache',
    'Content-Length': '571',#这个字符长度感觉有没有都可以
    'Content-Type': 'application/x-www-form-urlencoded',
    'Cookie': 'JSESSIONID=AFC7D6719362D1B0B120147B709F608D.worker4',#每次请求的cookie都不一样,但是同一个cookie应该可以重复使用
    'Referer': 'http://219.136.125.139/portalReceiveAction.do'#referer的意思应该是请求时的界面的地址
    }

#构造登录数据
post_data={
   'act': 'DISCONN',#下线的统一是这个
   'auth_type': 'PAP',
   'authkey': 'gzhlxy',
   'bank_acct': '',
   'chal_id': '',
   'chal_vector': '',
   'domain': 'GDHLXY',
   'freepasswd': '',
   'freeuser': '',
   'getpasstype': '0',
   'is189': 'true',
   'isCookies': '',
   'isHaveNotice': '0',
   'isRadiusProxy': 'false',
   'listgetpass': '0',
   'listpasscode': '0',
   'listwxauth': '0',
   'logintype': '0',
   'mac': '',
   'message': '%C4%FA%B5%C4%BF%C9%D3%C3%CC%EC%CA%FD%CE%AA%28%CC%EC%29%3A20.0',#下线的统一是这个
   'randstr': '',
   'req_id': '',
   'seq_id': '',
   'smsid': '0',
   'ssid': '',
   'templatetype': '1',
   'terminalType': '',
   'times': '12',
   'tname': '5',
   'url': 'http%3A%2F%2Fabout%3Ablank',#下线的统一是这个
   'userid': '1199605237638@GDHLXY',#不同
   'usertime': '588416373',#这个时间不同也是无所谓的
   'usertype': '0',
   'version': '0',
   'vlan': '',
   'weizhi': '0',
   'wlanacIp': '183.56.17.19',
   'wlanacname': 'gzhlxy',
   'wlanuserip': '10.110.75.38'#不同
          }   
#发送post请求登录网页
z=requests.post(post_addr,data=post_data,headers=my_headers)


3.自动获取计算机的ip地址

这段是百度的

#-*_coding:utf8-*-
import socket
hostname = socket.gethostname()
ipaddr = socket.gethostbyname(hostname)
print("您当前的主机名为" + hostname + "\n您当前的IP地址为" + ipaddr)


4.GUI界面

用pyinstaller打包的:


这里就要整合代码了,所以放出完整代码(注释很详细)

里面的上线部分和下线部分简化过了代码,删除了无用的信息

# -*- coding: utf-8-*-
import requests   #用来发送请求的库
import re         #正则表达式的库
import socket     #获取ip的库
from tkinter import *    #创建gui的库

#创建GUI
root = Tk()               #创建主窗口
root.title(u"华立一键上网工具")
root.geometry('300x280')
label=Label(root,text='华 立 专 用 一 键 上 网 工 具',font='Helvetica -12 bold')  #设置标签字体的初始大 小
label.pack()


#创建问题及文本框
l1=Label(root,text="请输入你的上网账号")
l1.pack()                 #指定包管理器放置组件  
q1_text = StringVar()       #文本框
q1 = Entry(root, textvariable = q1_text)
q1_text.set(" ")
q1.pack()

l2 = Label(root, text="请输入你的密码")
l2.pack()  #这里的side可以赋值为LEFT  RTGHT TOP  BOTTOM
q2_text = StringVar()
q2 = Entry(root, textvariable = q2_text)
q2_text.set(" ")
q2.pack()


#创建储存账号密码的文本
def getpd_num():
    f = open(r'data.txt','w')   
    q1 = q1_text.get()
    q2 = q2_text.get()
    data = [q1,q2]
    for each in data:
        f.write(each + '\n')
    f.close()
    print(u"储存账号密码成功")


#一键上网认证
def shangxian():
    post_addr="http://219.136.125.139/portalAuthAction.do"

    #构造头部信息
    my_headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
        'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',
        'Accept-Language': 'zh-CN',
        'Accept-Encoding': 'gzip, deflate',
        'Host':'219.136.125.139',
        'Connection': 'keep-alive',
        'Cache-Control': 'no-cache',
        'Content-Length': '511',#这个不同甚至没有无伤大雅
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cookie': 'JSESSIONID=19AE14CB4E83F1342FE36944A6609E86.worker4',
        'Referer': 'http://219.136.125.139/portalReceiveAction.do?wlanuserip=10.110.75.3&wlanacname=gzhlxy&wlanacip=183.56.17.19'
        }

    #构造登录数据
    post_data={
        'passwd': str(pw),#不同
        'userid': str(num) + '@GDHLXY',#不同
        'useridtemp': str(num),#不同
        'wlanacIp': '183.56.17.19',
        'wlanacname': 'gzhlxy',
        'wlanuserip': str(ipaddr)#不同
        }
#    print (post_data)

    #发送post请求上网认证
    z=requests.post(post_addr,data=post_data,headers=my_headers)


#一键下线
def xiaxian():
    post_addr="http://219.136.125.139/portalDisconnAction.do"

    #构造头部信息
    my_headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko',
        'Accept': 'text/html, application/xhtml+xml, image/jxr, */*',
        'Accept-Language': 'zh-CN',
        'Accept-Encoding': 'gzip, deflate',
        'Host':'219.136.125.139',
        'Connection': 'keep-alive',
        'Cache-Control': 'no-cache',
        'Content-Length': '571',#这个字符长度感觉有没有都可以
        'Content-Type': 'application/x-www-form-urlencoded',
        'Cookie': 'JSESSIONID=AFC7D6719362D1B0B120147B709F608D.worker4',#每次请求的cookie都不一样,但是同一个cookie应该可以重复使用
        'Referer': 'http://219.136.125.139/portalReceiveAction.do'#referer的意思应该是请求时的界面的地址
        }

    #构造登录数据
    post_data={
        'act': 'DISCONN',#下线的统一是这个
        'message': '%C4%FA%B5%C4%BF%C9%D3%C3%CC%EC%CA%FD%CE%AA%28%CC%EC%29%3A20.0',#下线的统一是这个
        'url': 'http%3A%2F%2Fabout%3Ablank',#下线的统一是这个
        'userid': str(num) + '@GDHLXY',#不同
        'wlanacIp': '183.56.17.19',
        'wlanacname': 'gzhlxy',
        'wlanuserip': str(ipaddr)#不同
        }
#    print(post_data)

    #发送post请求登录网页
    z=requests.post(post_addr,data=post_data,headers=my_headers)

if __name__ == '__main__':

    Button(root,text="提交",command = getpd_num).pack()   #提交数据的按钮

    #用正则表达式获取txt中储存的账号和密码    
    f = open(r'data.txt','r')
    data = f.read()
    num1 = re.search('(.*)\n',data).group(0)
    num = re.search('(\S+)',num1).group(0)
    print (num)
    f.close()

    f = open(r'data.txt','r')
    data = f.read()
    pw1 = re.search('\n(.*)',data).group(0)
    pw = re.search('(\S+)',pw1).group(0)
    print (pw)
    f.close()

   #获取本机ip地址
    hostname = socket.gethostname()          #获取主机名
    ipaddr = socket.gethostbyname(hostname)  #获取ipv4地址

    #一键上线的按钮
    Button(root,text="一键上网",command = shangxian).pack(side='left', padx=25, pady=10)   #一键上网按钮

    #一键下线的按钮
    Button(root,text="一键下线",command = xiaxian).pack(side = 'right',padx=25, pady=10)   #一键下线按钮

    #作者注释
    label=Label(root,text='---by allenc')
    label.pack(side = 'bottom')

root.mainloop()


5.自写的使用说明



6.写程序过程中遇到的问题:

1.账号密码提交写入data.txt部分后遇到的问题:

我要提取data.txt里储存的账号密码。不知道为什么创建文本框那里会自动生成一个空格在前面,为了消除这个空格的影响决定用正则表达式来获取



f = open(r'data.txt','r')  
data = f.read()
num1 = re.search('(.*)\n',data).group(0)
num = re.search('(\S+)',num1).group(0)
print (num)
f.close()

f = open(r'data.txt','r')
data = f.read()
pw1 = re.search('\n(.*)',data).group(0)
pw = re.search('(\S+)',pw1).group(0)
print (pw)
f.close()

就是先用一个正则'(.*)\n'获取换行符前的信息,再用正则'(\S+)'获得之前获得的数字,字母和下划线组成的账号(我猜没人乱输入下划线吧哈哈),然后用相同的思路获得密码。区别是第一个正则不同。


2.打包文件部分:

这里我遇到了一些问题查都查不到:用pyinstaller打包时,文件名不要带有中文,不然会报错。

还有打包完后要用到的文件要和程序放到同一目录下,我一开始没有放data出来,导致打开程序失败,纠结了半天。

这是因为程序里代码写法的原因,就不赘述了


3.做这个程序我查了很多类似的代码,学习写法。一键上线下线部分更是经历了无限的手动上线和下线才知道如何构造头和data的信息内容。还征用了舍友的电脑来做试验。上一部分记录:



最后

正在学习的同学可以看看有没有有用的部分,直接拿走吧。如果有错误或建议或问题请评论。也请大神赐教。。。

第一次写这种文章,表述不好请见谅

保持永远学习上进的状态QAQ

--by allenc


猜你喜欢

转载自blog.csdn.net/qq_42193971/article/details/80291863
今日推荐