You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python项目:从Ekahau JSON文件提取AP信息的实现疑问

从Ekahau导出的JSON中提取AP信息的最优方案

需求与JSON结构

首个Python项目需从Ekahau导出的JSON文件中提取无线AP信息,目标是生成如下格式的嵌套字典用于后续计算与导出:

accessPoints = {
    'AP001': {'floorPlanId':'', 'name':'Measured-AP-02:f5', 'mine':'true'},
    'AP002': {'floorPlanId':'Warehouse', 'name':'Measured-AP-cc:f8', 'mine':'true'}
}

Ekahau导出的JSON结构示例:

{
  "accessPoints": [
    {
      "location": {
        "floorPlanId": "0f422470-9c8f-41d7-a51f-a19dcd1208cc",
        "coord": {
          "x": 815.4422419685577,
          "y": 636.5659603554341
        }
      },
      "name": "WarehouseAP-4",
      "mine": true,
      "hidden": false,
      "userDefinedPosition": true,
      "noteIds": [],
      "vendor": "Aruba",
      "model": "AP-574 + ANT-2x2-2314 + ANT-4x4-5314",
      "tags": [],
      "id": "f27feef1-3800-4853-a0fe-21bc1da00d2f",
      "status": "CREATED"
    },
    {
      "location": {
        "floorPlanId": "0f422470-9c8f-41d7-a51f-a19dcd1208cc",
        "coord": {
          "x": 2710.3321941216677,
          "y": 981.6322624743677
        }
      },
      "name": "WarehouseAP-3",
      "mine": true,
      "hidden": false,
      "userDefinedPosition": true,
      "noteIds": [],
      "vendor": "Aruba",
      "model": "AP-574 + ANT-2x2-2314 + ANT-4x4-5314",
      "tags": [],
      "id": "535d8800-b264-4737-a4ba-1c69c518ad06",
      "status": "CREATED"
    }
  ]
}

最初尝试的问题

最初采用逐行读取、冒号分割键值对的方式,代码如下:

for file_name in all_json_files:  # loop for all json files
    if file_name.endswith(extension):  
        category = file_name[:-5]      
        json_file_path = temp_files + '/' + file_name
        open_file = open(json_file_path, 'r')
        skip_lines = 2  # amount of lines to skip
        current_line = 0    # reset current_line in each file
        list_of_keys = []  # leere list_of_keys für jede neue category/file
        list_of_values = []

        for lines in open_file:  # loop for each line in the json file
            lines.strip('{')
            lines.strip('}')
            if current_line >= skip_lines and len(lines.split(':')) > 1:  
                line_content = lines.split(':')  
                key = line_content[0].strip() 
                value = line_content[1].strip()  
                value = value[:-1]  # remove comma at end of line
                if key not in list_of_keys and value != '':
                    list_of_keys.append(key)
                    if value not in list_of_values:
                        list_of_values.append(value)
                    # for key, value in zip(list_of_keys, list_of_values):   # create database
                    #     database[key] = value
            current_line += 1
        open_file.close()

这种方式无法处理嵌套结构(比如location下的floorPlanId),也无法将每个AP的信息存入独立子字典,容错性极低(比如JSON格式换行、逗号位置变化都会导致解析失败)。

现有方案的合理性与优化

改用json.load()是最优选择,因为Python标准库的json模块专门用于解析结构化JSON数据,能自动处理嵌套结构、数据类型转换(比如布尔值true转为Python的True),且代码简洁、容错性高。

改进后的完整代码

在现有代码基础上,添加逻辑将解析后的JSON转换为目标格式的嵌套字典:

import json

extension = '.json'
# 定义需要提取的字段,可根据需求修改,支持嵌套路径
FIELDS_TO_EXTRACT = [
    ('floorPlanId', 'location.floorPlanId'),
    ('name', 'name'),
    ('mine', 'mine')
]

def get_nested_value(data, path):
    """从嵌套字典中根据路径提取值"""
    keys = path.split('.')
    current = data
    for key in keys:
        if key not in current:
            return ''
        current = current[key]
    # 转换布尔值为字符串(如果需要)
    return str(current).lower() if isinstance(current, bool) else current

for file_name in all_json_files:
    if file_name.endswith(extension):
        json_file_path = f"{temp_files}/{file_name}"
        with open(json_file_path, 'r') as file:
            data = json.load(file)
        
        # 生成目标格式的嵌套字典
        access_points = {}
        for idx, ap in enumerate(data.get('accessPoints', []), start=1):
            ap_key = f"AP{idx:03d}"  # 生成AP001、AP002格式的键
            ap_info = {}
            for field_name, path in FIELDS_TO_EXTRACT:
                ap_info[field_name] = get_nested_value(ap, path)
            access_points[ap_key] = ap_info
        
        # 后续可对access_points进行导出或计算操作
        print(access_points)

通用性说明

  • 通过FIELDS_TO_EXTRACT列表可灵活配置需要提取的字段,新增或修改字段无需修改核心循环逻辑
  • get_nested_value函数支持任意深度的嵌套字段提取,适配同类结构的JSON文件
  • 自动处理布尔值转换(如果不需要可删除对应逻辑)
  • 用data.get('accessPoints', [])避免JSON中无accessPoints字段时抛出异常

其他可选方案

如果需要更复杂的JSON查询(比如过滤特定条件的AP),可以考虑使用第三方库jsonpath-ng,安装后可通过类似XPath的语法提取数据:

# 需先安装:pip install jsonpath-ng
from jsonpath_ng import parse

# 示例:提取所有Aruba品牌的AP名称
jsonpath_expr = parse('$..accessPoints[?(@.vendor == "Aruba")].name')
matches = [match.value for match in jsonpath_expr.find(data)]

但对于当前需求,标准库的json模块已足够,无需额外依赖。

内容的提问来源于stack exchange,提问作者Ianus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 04:34:50