标签:
学校校园网的网络连接有免费连接和收费连接两种类型,可想而知收费连接浏览体验更佳,比如可以访问更多的网站。之前收费地址只能开通包月服务才可使用,后来居然有了每个月60小时的免费使用收费地址的优惠。但是,一旦连接了收费地址而忘记及时断开,60小时会很快用完。
为了节约收费地址的使用时间,采用如下方案:每隔1个小时,都在本机上断开校园网的收费连接,同时连接免费连接,这样,每次手动连接收费连接之后,最多使用1个小时,就会被自动断开。
1. python实现连接/断开网络连接
通过执行python脚本,实现访问 its.pku.edu.cn 并设置连接/断开。
通过fiddler抓包,分析从访问 its.pku.edu.cn,到填写账号密码,再到最后登陆成功的过程中,浏览器和网关交互的http request和response。
发现:
(1)访问 http://its.pku.edu.cn
request如下图:
网关response如下:
注意其中的%7C%3BkiDrqvfi7d%24v0p5Fg72Vwbv2%3B%7C
字符串,该字符串在后续的post中被使用。
(2)填写账号密码,连接到地址http://its.pku.edu.cn/cas/login
,request中的文本为:
发现其中含有账号和密码,以及&pwd_t=%E5%AF%86%E7%A0%81
(这个是固定的字符),还有字符串%7C%3BkiDrqvfi7d%24v0p5Fg72Vwbv2%3B%7C
(这是从上次的response中获得的)。
...
中间浏览器还连接了 http://its.pku.edu.cn/netportal/
http://its.pku.edu.cn/netportal/netportal_UTF-8.jsp
http://its.pku.edu.cn/netportal/blank_UTF-8.html
http://its.pku.edu.cn/connect.htm
等url,通过单步跟踪发现,这些url对最终的网络连接成功与否没有任何影响,因此不予考虑。
...
(3)设置连接操作,浏览器连接到 http://its.pku.edu.cn/netportal/ipgwopen?sid=449
现在要知道449 是如何来的,从前面的浏览器和网关之间交互的几个response中没有发现449,考虑449可能是由函数生成的。在url http://its.pku.edu.cn/netportal/js/funcs_v2.js?509173
的response中发现了
function doaction3(_d){ if(_d.indexOf("?")!=-1){ window.frames[‘mycontent‘].location.href=_d+"&sid="+Math.floor(Math.random()*1000); }else{ window.frames[‘mycontent‘].location.href=_d+"?sid="+Math.floor(Math.random()*1000); }}
的js函数,原来449是随机生成的一个值。
注意到http://its.pku.edu.cn/netportal/ipgwopen?sid=449
中的 ipgwopen,这个是连接的类型表示,通过分析http://its.pku.edu.cn/netportal/netportal_UTF-8.jsp
的response内容可以发现: ipgwopen 表示连接免费地址
ipgwopenall 表示连接免费和收费地址
ipgwclose 表示断开本机连接
ipgwcloseall 表示断开所有连接
步骤(3)之后,发现就可以正常上网,因此在使用python模拟浏览器登录网关的时候,只需要模拟1-3这三个步骤即可,需要注意获取步骤1 response中的字符串,并在步骤2中post到网关,以及步骤3的sid为随机生成的整数。
python代码实现 源代码使用python3 实现,因此需要机器安装 python3 环境。
#!/usr/bin/env python3 ‘‘‘python crawler ‘‘‘ #encoding:UTF-8 import re import os import gzip import random import sys import time import urllib import urllib.request import http.cookiejar import http.client def MakeOpener(head = { ‘Connetion‘: ‘Keep-Alive‘, ‘Accept‘: ‘text/html, application/xhtml+xml, */*‘, ‘Accept-Language‘: ‘en-US, en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3‘, ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:39.0) Gecko/20100101 Firefox/39.0‘}): cj = http.cookiejar.CookieJar() pro = urllib.request.HTTPCookieProcessor(cj) #Python自动处理cookie opener = urllib.request.build_opener(pro) #用于打开url的opener # urllib.request.install_opener(opener) SetOpenerHeader(opener, head) #构造http头部数据,模仿一个浏览器对url进行访问 return opener #构造 opener的头部信息, 参数header为一个字典,如上面的 ‘Connetion‘: ‘Keep-Alive‘, ‘Accept‘: ‘text/html, application/xhtml+xml, */*‘, #将字典中的key和value对,变成元组(k,v)然后加入到 opener的 addheaders 列表中 def SetOpenerHeader(opener, header): tmp_header = [] for key, value in header.items(): elem = (key, value) tmp_header.append(elem) opener.addheaders = tmp_header #http返回的数据可能为经过压缩的,若网页经过压缩,则解压。此时得到的数据为字节数组,然后将网页按照字符编码解析这些字节数组 #将字节数组翻译为 字符串 def DecodePageData(data): try: data = gzip.decompress(data) except: # print(‘exception occurs when decompress as gzip‘) pass result = data encode_options = [‘utf-8‘, ‘GBK‘, ‘gb2312‘] for encode_op in encode_options: #尝试多种编码的解析,将http 返回的数据(字节数组)翻译为字符串 try: result = data.decode(encode_op) except: continue else: break return result def GetEncodedPostData(page_data, username1, password, free_gw = True): #获取服务端进行验证的一个字符串,通过fiddler中对比知道,需要在本地下次post的时候,添加这个验证字符串 cer = re.compile(r‘\(\"username\"\)\.value\+unescape\(\"(.+)\"\)\+‘) encode_str = ‘‘ for m in cer.finditer(page_data): encode_str = m.group(1) break if not encode_str: print(‘parse username generating formula failed...‘) return result = ‘username1=‘ + username1 result += ‘&password=‘ result += password result += ‘&pwd_t=%E5%AF%86%E7%A0%81‘ result += ‘&fwrd=‘ if free_gw: result += ‘free‘ else: result += ‘fee‘ result += ‘&username=‘ result += username1 result += encode_str result += password result += encode_str if free_gw: result += ‘12‘ else: result += ‘11‘ return result #根据option执行不同的操作, user_name 和 passwd 为校园网账户和密码 def PkuGateWayOperation(option, user_name = ‘1401214230‘, passwd = ‘xxxxx‘): #伪造的一个浏览器访问url的http头部 header = { ‘Connection‘: ‘Keep-Alive‘, ‘Accept‘: ‘*/*‘, ‘Accept-Language‘: ‘en-US, en;q=0.8,zh-Hans-CN;q=0.5,zh-Hans;q=0.3‘, ‘User-Agent‘: ‘Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:39.0) Gecko/20100101 Firefox/39.0‘, ‘Accept-Encoding‘: ‘gzip, deflate‘, ‘Host‘: ‘its.pku.edu.cn‘ } #第一步,模拟浏览器登录 http://its.pku.edu.cn/ url = ‘http://its.pku.edu.cn/‘ opener = MakeOpener(header) op = opener.open(url) data = DecodePageData(op.read()) header[‘Referer‘] = ‘http://its.pku.edu.cn/‘ url = ‘http://its.pku.edu.cn/cas/login‘ SetOpenerHeader(opener, header) free_gw = True if (option == 2): free_gw = False #根据返回的网页数据,设置post数据,主要是用户名、密码、连接方式 post_data = GetEncodedPostData(data, user_name, passwd, free_gw) #第二步,post用户名和密码,在 post_data中,其中还添加了一些验证信息(从上一次response中获取) op = opener.open(url, post_data.encode(encoding=‘utf-8‘)) option_str = ‘ipgwopen‘ if option == 2: option_str = ‘ipgwopenall‘ elif option == 3: option_str = ‘ipgwclose‘ elif option == 4: option_str = ‘ipgwcloseall‘ #添加操作选项 和一个随机数! url = ‘http://its.pku.edu.cn/netportal/‘ + option_str + ‘?sid=‘ + str(random.randint(1,999)) #第三部,设置连接操作 op = opener.open(url) #命令行参数,来设置不同的操作 #1 连接免费网址 #2 连接收费网址 #3 断开本机连接 #4 断开所有连接 #5 断开本机连接,然后重新连接免费地址(这样是为了设置程序每隔1个小时执行一次,防止收费地址连接时间过长。定时断网,节约收费地址的使用时间) if __name__ == ‘__main__‘: if len(sys.argv) != 2: print(‘usage <option: 1 (connect free), 2 (connect global), 3 (disconnect this computer), 4 (disconnect all), 5(disconnect this computer and connect free)‘) exit(1) option = int(sys.argv[1]) if option < 1 or option > 5: print(‘invalid option number: ‘ + sys.argv[1]) print(‘usage <option: 1 (connect free), 2 (connect global), 3 (disconnect this computer), 4 (disconnect all), 5(disconnect this computer and connect free)‘) exit(1) if option == 5: PkuGateWayOperation(3) PkuGateWayOperation(1) fb = open(‘G:\\workspace\\MyTools\\Python\\log.txt‘, ‘a‘) fb.write(‘this program runs at ‘ + time.strftime(‘%Y-%m-%d %H:%M:%S‘,time.localtime(time.time())) ) fb.close() else: PkuGateWayOperation(option)
2. 每1小时自动执行
linux下比较方便,直接设置 crontab即可。
windows下可以设置机器的自动任务计划,具体步骤如下:
(1)开始->所有工具->windows管理工具->任务计划程序
(2)创建任务
(2.1)常规 ——填写程序名称(随意)
(2.2)触发器 ——新建,设置为每天固定时间开始执行,每隔一个小时重复一次
(2.3)操作 ——新建,设置为执行python脚本,且设置正确的命令行参数 (包括python脚本路径和参数5)
标签:
原文地址:http://www.cnblogs.com/gtarcoder/p/4903253.html