Python解析JSON计数块

cedebl8k  于 2023-03-20  发布在  Python
关注(0)|答案(2)|浏览(94)

我有一个从Wireshark导出的**.json**文件,其中包含以下示例:

"_source": {
  "layers": {
    "frame": {
      "frame.encap_type": "1",
      "frame.time": "Jan 23, 2018 10:32:28.074649000 Mitteleurop\u00c3\u00a4ische Zeit",
      "frame.offset_shift": "0.000000000",
      "frame.time_epoch": "1516699948.074649000",
      "frame.time_delta": "0.000036000",
      "frame.time_delta_displayed": "0.000036000",
      "frame.time_relative": "141.761654000",
      "frame.number": "18",
      "frame.len": "76",
      "frame.cap_len": "76",
      "frame.marked": "0",
      "frame.ignored": "0",
      "frame.protocols": "eth:ethertype:pn_rt:pn_dcp"
    },
    "eth": {
      "eth.dst": "60:38:e0:e3:16:05",
      "eth.dst_tree": {
        "eth.dst_resolved": "BelkinIn_e3:16:05",
        "eth.addr": "60:38:e0:e3:16:05",
        "eth.addr_resolved": "BelkinIn_e3:16:05",
        "eth.lg": "0",
        "eth.ig": "0"
      },
      "eth.src": "00:a0:45:84:3c:9c",
      "eth.src_tree": {
        "eth.src_resolved": "PhoenixC_84:3c:9c",
        "eth.addr": "00:a0:45:84:3c:9c",
        "eth.addr_resolved": "PhoenixC_84:3c:9c",
        "eth.lg": "0",
        "eth.ig": "0"
      },
      "eth.type": "0x00008892"
    },
    "pn_rt": {
      "pn_rt.frame_id": "65277"
    },
    "pn_dcp": {
      "pn_dcp.service_id": "3",
      "pn_dcp.service_type": "1",
      "pn_dcp.xid": "0x00000007",
      "pn_dcp.reserved16": "0",
      "pn_dcp.data_length": "50",
      "pn_dcp.block": {
        "pn_dcp.option": "2",
        "pn_dcp.suboption_device": "2",
        "pn_dcp.block_length": "5",
        "pn_dcp.block_info": "0",
        "pn_dcp.suboption_device_nameofstation": "dut"
      },
      "pn.padding": "data",
      "pn_dcp.block": {
        "pn_dcp.option": "2",
        "pn_dcp.suboption_device": "3",
        "pn_dcp.block_length": "6",
        "pn_dcp.block_info": "0",
        "pn_dcp.suboption_vendor_id": "0x00000174",
        "pn_dcp.suboption_device_id": "0x00001234"
      },
      "pn_dcp.block": {
        "pn_dcp.option": "1",
        "pn_dcp.suboption_ip": "1",
        "pn_dcp.block_length": "8",
        "pn.undecoded": "data",
        "pn.undecoded_tree": {
          "_ws.expert": {
            "pn.undecoded_data": "",
            "_ws.expert.message": "Undecoded Data, 8 bytes",
            "_ws.expert.severity": "6291456",
            "_ws.expert.group": "83886080"
          }
        }
      },
      "pn_dcp.block": {
        "pn_dcp.option": "1",
        "pn_dcp.suboption_ip": "2",
        "pn_dcp.block_length": "14",
        "pn_dcp.suboption_ip_block_info": "1",
        "pn_dcp.subobtion_ip_ip": "192.168.0.50",
        "pn_dcp.subobtion_ip_subnetmask": "255.255.255.0",
        "pn_dcp.suboption_ip_standard_gateway": "0.0.0.0"
      }
    }
  }
}

我可以用Python找出设置了哪个dcp_option,使用了哪个子选项,但是我只得到了最后一个pn_dcp.block参数,所以我的问题是:是否可以从这个字典中计算出pn_dcp.block?是否可以读出所有pn_dcp.block信息?
下面是示例代码:

if __name__ == '__main__':
    j = None
    with open(INFILE, 'r') as f:
        j = json.load(f)

    for p in j:
        r = build_line(p)
def build_line(p):
    p = p['_source']['layers']
    # DCP ----------------------
    dcp = p['pn_dcp']
    dcp_id = dcp['pn_dcp.service_id']
    dcp_type = dcp['pn_dcp.service_type']

# There is no direct option in Get -------
    if not 'pn_dcp.block' in dcp:
        dcp_block = dcp
    else:
        dcp_block = dcp['pn_dcp.block']
    dcp_option = dcp_block['pn_dcp.option']

# Differenz options --------------------------------
    if dcp_option == '1':
        dcp_suboption = dcp_block['pn_dcp.suboption_ip']
    elif dcp_option == '2':
        dcp_suboption = dcp_block['pn_dcp.suboption_device']
    elif dcp_option == '3':
        dcp_suboption = dcp_block['pn_dcp.suboption_dhcp']
    elif dcp_option == '5':
        dcp_suboption = dcp_block['pn_dcp.suboption_control']
    elif dcp_option == '6':
        dcp_suboption = dcp_block['pn_dcp.suboption_deviceinitiative']
    elif dcp_option == '255':
        dcp_suboption = dcp_block['pn_dcp.suboption_all']
    elif dcp_option == '0':
        dcp_suboption = dcp_block['pn_dcp.reserved16']
    else:
        return 'other' # for no option find

# Format -------------------------------------------------------------
    act = "%02x%02x" % (int(dcp_id, 10), int(dcp_type, 10))
    option = "%02x%02x" % (int(dcp_option, 10), int(dcp_suboption, 10))

# Options ------------------------------------------------------------------
options = OPTIONS.get(option, 'invalid')
activity = ACTIVITIES.get(act, 'invalid')
Event = activity + options

我希望这能有所帮助。我正在从sourcelayers再到pn_dcp的块中进行箝位。然后我正在搜索pn_dcp.block块,并读出dcp_optionsdcp_suboptions

xuo3flqw

xuo3flqw1#

  • 是否可以从此字典中计算pn_dcp.block?*
    pn_dcp.block是此字典中的双关键字。

密钥必须是唯一的,因此它总是被最后一次出现的密钥覆盖。

  • 是否可以读取所有pn_dcp.块信息?*

差不多吧,你可以把object_pairs_hook加到json.load上:

pn_dcp_blocks=[]
def saveBlocks(*args):
if args[0][0][0]=="pn_dcp.option":
    global pn_dcp_blocks
    pn_dcp_blocks.append(args[0])

with open(INFILE, 'r') as f:
    j = json.load(f, object_pairs_hook =saveBlocks)

它会输出一个如下的结构:

pn_dcp_blocks = {list} <class 'list'>: 
 0 = {list} <class 'list'>: 
  0 = {tuple} <class 'tuple'>: ('pn_dcp.option', '2')
  1 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device', '2')
  2 = {tuple} <class 'tuple'>: ('pn_dcp.block_length', '5')
  3 = {tuple} <class 'tuple'>: ('pn_dcp.block_info', '0')
  4 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device_nameofstation', 'dut')
  __len__ = {int} 5
 1 = {list} <class 'list'>:
  0 = {tuple} <class 'tuple'>: ('pn_dcp.option', '2')
  1 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device', '3')
  2 = {tuple} <class 'tuple'>: ('pn_dcp.block_length', '6')
  3 = {tuple} <class 'tuple'>: ('pn_dcp.block_info', '0')
  4 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_vendor_id', '0x00000174')
  5 = {tuple} <class 'tuple'>: ('pn_dcp.suboption_device_id', '0x00001234')
  __len__ = {int} 6
 2 = {list} <class 'list'>: 
  <deleted for readability>
 3 = {list} <class 'list'>: 
  <deleted for readability>
 __len__ = {int} 4

请注意:您将丢失这些元组中的缩进树

eoxn13cs

eoxn13cs2#

问题是pn_dcp.block是一个重复的键,所以当你把json解析成一个对象或字典时,第二个pn_dcp.block会重写第一个,唯一的方法是预先过滤文件,这样名字就可以是唯一的。

import re

i = 0

def replace(match):
    global i
    i += 1
    return 'pn_dcp.block%i' % i

with open('data.json') as f:
    data = f.read()

formatted = json.loads(re.sub("pn_dcp.block([^_])", replace, data))

然后,您可以继续您的代码并使用i循环所有pn_dcp.block

相关问题