參考:https://testerhome.com/topics/5276
har導出格式如下:
{
'log':
{
'pages': [],
'comment':
'exported @ 2019/6/28 15:01:27',
'entries':
[
{
'time':
3210,
'connection':
'ClientPort:50377;
EgressPort:53633',
'comment':
'[#43]',
'request':
{
'headersSize':
667,
'postData': {
'text':
'{
"checksum":"1557025867",
"language":""
}',
'mimeType':
'application/json'
},
'queryString': [],
'headers': [
{
'name':
'Host',
'value':
'bankpreidc.zatech.com'
},
{
'name':
'Content-Type',
'value':
'application/json'
},
{
'name':
'channelId',
'value':
'10000'
},
{
'name':
'Accept',
'value':'heheh'},
{
'name':
'timestamp',
'value':
'1561693450'},
{
'name':
'appVersion',
'value':
'v1.0.0'},
{
'name':
'OS',
'value':
'iOS'},
{
'name':
'Accept-Encoding',
'value':
'gzip;q=1.0, compress;q=0.5'},
{
'name':
'apiVersion',
'value':
'v1.0.0'},
{
'name':
'Accept-Language',
'value':
'zh-Hans-CN;q=1.0'},
{
'name':
'language',
'value':
'zh'},
{
'name':
'did',
'value':
'NTIzOTIxNDYwMzMyM2NjZjk1OGM5NjBmYzNlNzg2OTYtZTkxNzg1MzYzNjA4NGM0Mjg4Njg3MmFhNzExMDE1YTgwMDAyLXIwWUtuK0MrS1Y2eDBteWs3WnhDYmQ2ZnovTT0='}, {
'name':
'User-Agent',
'value':
'AnAnLifeInsurance_iOS/1.0.0 (com.zhonganio.zabank; build:357; iOS 11.4.1) Alamofire/4.8.2'},
{
'name':
'Content-Length',
'value':
'39'},
{
'name':
'Connection',
'value':
'keep-alive'},
{
'name':
'reqSeq',
'value':
'9d3157c83dc46cd64cc65694c39163ba'},
{
'name':
'OSVersion',
'value':
'11.4.1'}
],
'bodySize':
39,
'url':
'https://XXXXX/ci/dict/find',
'cookies': [],
'method':
'POST',
'httpVersion':
'HTTP/1.1'
},
'timings':
{
'blocked':
-1,
'ssl':
0,
'receive':
2175,
'wait':
1034,
'dns':
0,
'send':
1,
'connect':
0
},
'response':
{
'headersSize':
213,
'bodySize':
1157023,
'statusText':
'200',
'redirectURL':
'',
'status':
200,
'httpVersion':
'HTTP/1.1',
'cookies': [],
'content':
{
'compression':
-259,
'comment':
'Body length exceeded fiddler.importexport.HTTPArchiveJSON.MaxTextBodyLength, so body was omitted.',
'size':
1156764,
'mimeType':
'application/json;charset=UTF-8'
},
'headers':
[
{
'name':
'Server',
'value':
'nginx'},
{
'name':
'Date',
'value':
'Fri, 28 Jun 2019 03:44:13 GMT'},
{
'name':
'Content-Type',
'value':
'application/json;charset=UTF-8'},
{
'name':
'Transfer-Encoding',
'value':
'chunked'},
{
'name':
'Connection',
'value':
'keep-alive'},
{
'name':
'X-Application-Context',
'value':
'za-bank-gateway:8080'}
]
},
'startedDateTime':
'2019-06-28T11:43:16.0675861+08:00',
'cache': {}
},
{
XXXX
}
,
。。。
],
'creator':
{
'name':
'Fiddler',
'comment':
'https://fiddler2.com',
'version':
'5.0.20182.28034'
},
'version':
'1.2'
}
}
代碼如下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from optparse import OptionParser
import os
import sys
import json
# check env
if sys.version_info < (3, 4):
raise RuntimeError('At least Python 3.4 is required.')
restype = ('js', 'css', 'jpg', 'gif', 'ico', 'png')
def list2dic(headers):
header_dic = dict()
for head in headers:
if head['name'] in header_dic:
header_dic[head['name']] = header_dic[head['name']] + ',' + head['value']
else:
header_dic[head['name']] = head['value']
return header_dic
def dictoand(dct):
res_list = list()
for tp in dct:
res_list.append('%s=%s' % (tp['name'], tp['value']))
return '&'.join(res_list)
def dict2lr(lrsc):
tmpl = '''
web_custom_request("%(name)s",
"URL=%(url)s",
"Method=%(method)s",
"Resource=%(res)s",
"Referer=%(referer)s",
"EncType=%(enctype)s",
"Body=%(body)s",
LAST);'''
# url
url = lrsc['url']
method = lrsc['method']
name = url.split('/')[-1]
name = name.split('?')[0]
suff = url.split('.')[-1]
# Resource type
global restype
res = '0'
if suff in restype:
res = '1'
# Content-Type
enctype = ''
if 'Content-Type' in lrsc:
enctype = lrsc['Content-Type']
# Referer
referer = ''
if 'Referer' in lrsc:
referer = lrsc['Referer']
# Body
body = ''
if 'posttext' in lrsc:
body = lrsc['posttext']
elif 'postparams' in lrsc:
body = dictoand(lrsc['postparams'])
body = body.replace('"', '\\"')
res = tmpl % {'name': name, 'url': url, 'method': method, 'enctype': enctype, 'referer': referer, 'res': res,
'body': body}
# Head
if 'SOAPAction' in lrsc:
res = ("\n" + ' web_add_header("SOAPAction", "%s")' + ";\n" + res) % lrsc['SOAPAction']
return res
def parhar(harfile):
print('harfile:',harfile)
res = list()
try:
import codecs
# with codecs.open(harfile, 'r', 'utf-8-sig') as in_file:
# for line in in_file.readlines():
# print(line)
FH = codecs.open(harfile, mode='r', encoding='utf-8-sig')
# FH = open(harfile, mode='r')
print('FH:',FH)
all = json.load(FH)
FH.close()
except Exception as ex:
print('Open har file errr: %s' % ex)
quit()
print(all)
har_ver = all['log']['version']
creater = all['log']['creator']['name']
entries = all['log']['entries']
ct = len(entries) # 請求實體數據
for et in entries:
stm = et['startedDateTime']
req = et['request'] # 請求數據
rsp = et['response'] # 返回數據
lrsc = dict()
if '_charlesStatus' in rsp and rsp['_charlesStatus'] != 'Complete':
continue
# 獲取請求入參的主要數據
lrsc['method'] = req['method']
lrsc['url'] = req['url']
headers = req['headers']
print('headers:', headers)
# http head
header_dic = list2dic(headers)
print('headers dict:', header_dic)
if 'SOAPAction' in header_dic:
lrsc['SOAPAction'] = header_dic['SOAPAction'].replace('"', '\\"')
if 'Referer' in header_dic:
lrsc['Referer'] = header_dic['Referer']
if 'Content-Type' in header_dic:
lrsc['Content-Type'] = header_dic['Content-Type']
if lrsc['method'] == 'GET':
pass
elif lrsc['method'] == 'POST':
if 'postData' in req:
if 'text' in req['postData']:
lrsc['posttext'] = req['postData']['text']
if 'params' in req['postData']:
lrsc['postparams'] = req['postData']['params']
if 'mimeType' in req['postData']:
lrsc['postmime'] = req['postData']['mimeType']
else:
continue
print('V:',lrsc)
res.append(dict2lr(lrsc))
return res
if __name__ == '__main__':
parse = OptionParser()
parse.add_option("-f", action="store", dest="harfile", help='harfile path')
parse.add_option("-o", action="store", dest="lrfile", help='action.c path')
(options, args) = parse.parse_args()
print('-----------------------')
print(options)
print('-----------------------')
print(args)
if options.harfile is None or options.lrfile is None:
parse.print_help()
quit()
if not os.path.exists(options.harfile):
print('Har file %s not exist' % options.harfile)
quit()
print("1")
res = parhar(options.harfile)
print("**********************************8888888")
print(res)
file = open(options.lrfile, mode='w', encoding='utf-8')
for sc in res:
file.write(sc)
file.write("\n")
file.close()
print('Output to %s' % options.lrfile)