zoukankan      html  css  js  c++  java
  • pytho 解析fiddler 导出的har文件代码,自动录入api

    参考: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 = (" " + ' web_add_header("SOAPAction", "%s")' + "; " + 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(" ")
    file.close()
    print('Output to %s' % options.lrfile)
  • 相关阅读:
    基础系列(3)—— 高级数据类型
    ASP.NET MVC5 基础系列(3)——视图
    JSP学习笔记
    Tomcat学习笔记
    Tomcat学习笔记
    Tomcat学习笔记
    Tomcat学习笔记
    Tomcat学习笔记
    MySQL学习笔记(5)
    MySQL学习笔记(4)
  • 原文地址:https://www.cnblogs.com/yoyo008/p/11103439.html
Copyright © 2011-2022 走看看