当前位置:首页 > 文章列表 > 文章 > python教程 > Python多对象JSON解析方法与技巧

Python多对象JSON解析方法与技巧

2025-12-27 16:09:41 0浏览 收藏

今天golang学习网给大家带来了《Python解析多对象JSON策略与技巧》,其中涉及到的知识点包括等等,无论你是小白还是老手,都适合看一看哦~有好的建议也欢迎大家在评论留言,若是看完有所收获,也希望大家能多多点赞支持呀!一起加油学习~

处理非标准多对象JSON响应:Python解析策略与实践

本教程旨在解决API响应中包含多个JSON对象但缺乏标准数组封装和逗号分隔的非规范情况。我们将深入探讨一种基于行内容特征识别JSON对象边界的Python解析策略,通过示例代码演示如何将这些独立且无分隔符的JSON字符串准确地分割并解析为独立的Python字典列表,确保数据能够被正确处理和利用。

在与各种API交互时,我们通常期望接收到符合RFC 8259标准的JSON响应。然而,在某些特殊场景下,API可能返回一种非标准的JSON结构,其中包含多个独立的JSON对象,但这些对象既没有被包裹在一个外层数组 [] 中,也没有通过逗号 , 进行分隔。它们可能只是简单地一个接一个地拼接在一起,如下所示:

{
  "key1": "value1",
  "key2": "value2"
}
{
  "key3": "value3",
  "key4": "value4"
}

直接使用 json.loads() 解析此类字符串会导致 json.JSONDecodeError,因为整个字符串不构成一个有效的JSON文档(既不是单个对象也不是单个数组)。本教程将介绍一种在Python中有效解析此类非标准响应的策略。

理解非标准JSON结构

上述非标准结构的核心挑战在于缺乏明确的分隔符。每个JSON对象都以 { 开始,以 } 结束。当一个JSON对象结束后,下一个JSON对象可能紧随其后开始。这种模式提供了一个关键线索:一个对象的结束符 } 后面紧跟着下一个对象的开始符 {,通常在不同的行上。我们可以利用这一特征来识别对象之间的边界。

核心解析策略

我们的策略是逐行读取原始响应数据,并寻找表示一个JSON对象结束和另一个JSON对象开始的特定行模式。具体来说,当遇到一行内容仅为 } 且紧接着下一行内容仅为 { 时,这便是一个对象边界的信号。通过这种方式,我们可以将原始的非标准字符串分割成多个独立的、有效的JSON字符串片段,然后对每个片段单独进行解析。

Python实现示例

以下Python代码演示了如何应用上述策略来解析此类非标准的多对象JSON响应。

import json

# 示例非标准JSON响应数据
non_standard_json_data = '''
{
"self": "https://example1.com",
"key": "keyOne",
"name": "nameOne",
"emailAddress": "mailOne",
"avatarUrls": {
  "48x48": "https://test.com/secure/useravatar?avatarId=1",
  "24x24": "https://test.com/secure/useravatar?size=small&avatarId=1",
  "16x16": "https://test.com/secure/useravatar?size=xsmall&avatarId=1",
  "32x32": "https://test.com/secure/useravatar?size=medium&avatarId=1"
},
"displayName": "displayNameOne",
"active": true,
"timeZone": "Europe",
"locale": "en_UK"
}
{
"self": "https://example2.com",
"key": "keyTwo",
"name": "nameTwo",
"emailAddress": "mailTwo",
"avatarUrls": {
  "48x48": "https://test.com/secure/useravatar?avatarId=2",
  "24x24": "https://test.com/secure/useravatar?size=small&avatarId=2",
  "16x16": "https://test.com/secure/useravatar?size=xsmall&avatarId=2",
  "32x32": "https://test.com/secure/useravatar?size=medium&avatarId=2"
},
"displayName": "displayNameTwo",
"active": false,
"timeZone": "Europe",
"locale": "en_US"
}
'''

def parse_non_standard_multi_json(raw_data: str) -> list[dict]:
    """
    解析包含多个非标准连接JSON对象的字符串。

    Args:
        raw_data: 包含多个JSON对象的原始字符串。

    Returns:
        一个包含所有解析出的JSON字典的列表。
    """
    parsed_objects = []

    # 将原始数据按行分割,并移除每行首尾的空白字符
    lines = [line.strip() for line in raw_data.splitlines()]

    # 过滤掉空行,确保只处理有效内容行
    lines = [line for line in lines if line]

    current_object_start_index = 0

    for i, line in enumerate(lines):
        # 寻找对象边界:当前行是'{'且前一行是'}'
        if i > 0 and line == "{" and lines[i-1] == "}":
            # 提取前一个完整的JSON对象的所有行
            json_segment_lines = lines[current_object_start_index:i]
            # 将这些行拼接成一个完整的JSON字符串
            json_string = "".join(json_segment_lines)
            try:
                # 解析并添加到结果列表
                parsed_objects.append(json.loads(json_string))
            except json.JSONDecodeError as e:
                print(f"解析JSON片段失败: {e}\n片段内容: {json_string}")
                # 根据实际需求处理错误,例如跳过或记录

            # 更新下一个对象的起始索引
            current_object_start_index = i

    # 处理最后一个JSON对象
    if current_object_start_index < len(lines):
        json_segment_lines = lines[current_object_start_index:]
        json_string = "".join(json_segment_lines)
        try:
            parsed_objects.append(json.loads(json_string))
        except json.JSONDecodeError as e:
            print(f"解析最后一个JSON片段失败: {e}\n片段内容: {json_string}")

    return parsed_objects

# 调用解析函数
result_list = parse_non_standard_multi_json(non_standard_json_data)

# 打印解析结果以验证
print(f"成功解析 {len(result_list)} 个JSON对象:")
for idx, obj in enumerate(result_list):
    print(f"\n--- 对象 {idx + 1} ---")
    print(json.dumps(obj, indent=2, ensure_ascii=False))

代码详解

  1. 导入 json 模块: Python内置的 json 库用于JSON数据的序列化和反序列化。
  2. non_standard_json_data: 这是一个多行字符串,模拟了我们遇到的非标准JSON响应数据。
  3. parse_non_standard_multi_json(raw_data) 函数:
    • parsed_objects = []: 初始化一个空列表,用于存储所有成功解析的JSON字典。
    • lines = [line.strip() for line in raw_data.splitlines()]: 将原始字符串按行分割,并使用 strip() 方法移除每行开头和结尾的空白字符(包括换行符、空格等)。这一步非常关键,因为它确保了 "{" 和 "}" 这样的字符串能够被准确匹配。
    • lines = [line for line in lines if line]: 过滤掉所有空行,避免它们干扰判断逻辑。
    • current_object_start_index = 0: 记录当前正在构建的JSON对象在 lines 列表中的起始行索引。
    • 循环遍历行:
      • for i, line in enumerate(lines): 迭代处理每一行及其索引。
      • if i > 0 and line == "{" and lines[i-1] == "}": 这是核心的边界检测逻辑。它检查:
        • i > 0: 确保不是第一行,因为需要比较前一行。
        • line == "{": 当前行是否为 {。
        • lines[i-1] == "}": 前一行是否为 }。
        • 如果这三个条件都满足,说明我们找到了一个JSON对象的结束和下一个JSON对象的开始,即一个对象边界。
      • 提取和解析片段: 当检测到边界时,从 current_object_start_index 到当前行 i 之间的所有行被认为是前一个完整的JSON对象。
        • json_segment_lines = lines[current_object_start_index:i]: 截取这些行。
        • json_string = "".join(json_segment_lines): 将这些行重新拼接成一个完整的JSON字符串。
        • json.loads(json_string): 使用 json.loads() 解析这个片段,并将其添加到 parsed_objects 列表中。
        • current_object_start_index = i: 更新 current_object_start_index 为当前行 i,为下一个JSON对象的解析做准备。
      • 错误处理: try-except json.JSONDecodeError 块用于捕获在解析单个JSON片段时可能发生的错误,提高了程序的健壮性。
    • 处理最后一个JSON对象: 循环结束后,current_object_start_index 到 lines 列表末尾的所有行构成了最后一个JSON对象。需要单独处理它,以确保所有对象都被解析。

注意事项与最佳实践

  1. 数据格式的严格性: 此方法高度依赖于原始数据中 } 和 { 必须单独成行且紧密相连的模式。如果JSON对象内部的字符串值或键包含了 } 或 {,或者格式有其他变体(例如,} 和 { 不在独立行,或者中间有其他非空字符),此方法可能需要调整甚至失效。因此,在实际应用前,务必仔细检查非标准JSON响应的实际格式。
  2. 空白字符处理: line.strip() 和过滤空行是至关重要的。如果原始数据中 } 或 { 前后存在不必要的空白字符,或者它们与JSON内容混杂在同一行,解析逻辑将受到影响。
  3. 错误处理: 在生产环境中,应加强 json.JSONDecodeError 的处理。例如,可以记录错误片段、跳过损坏的对象,或者抛出自定义异常,以便上层应用能够感知并处理数据不完整的情况。
  4. 性能考量: 对于非常大的响应数据,逐行处理并多次拼接字符串可能会有一定的性能开销。如果性能成为瓶颈,可以考虑使用正则表达式进行更高效的分割,但正则表达式的编写会更加复杂,且需要确保其鲁棒性。
  5. API规范化: 最根本的解决方案是与API提供方沟通,请求他们返回符合标准的JSON格式(例如,将所有对象封装在一个JSON数组中)。这不仅简化了客户端解析逻辑,也提高了数据的互操作性和可靠性。

总结

尽管API返回非标准JSON格式是一种不理想的情况,但通过本教程介绍的基于行内容特征识别边界的策略,我们能够有效地在Python中解析此类数据。该方法的核心在于将原始数据分割成多个独立的、可解析的JSON字符串片段,然后逐一处理。理解这种策略及其潜在的局限性,将有助于开发者在面对各种复杂数据格式时,构建更健壮和灵活的数据处理方案。

终于介绍完啦!小伙伴们,这篇关于《Python多对象JSON解析方法与技巧》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~golang学习网公众号也会发布文章相关知识,快来关注吧!

美团外卖每日领券攻略美团外卖每日领券攻略
上一篇
美团外卖每日领券攻略
JavaScript生成器与迭代器使用教程
下一篇
JavaScript生成器与迭代器使用教程
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ChatExcel酷表:告别Excel难题,北大团队AI助手助您轻松处理数据
    ChatExcel酷表
    ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
    3452次使用
  • Any绘本:开源免费AI绘本创作工具深度解析
    Any绘本
    探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
    3659次使用
  • 可赞AI:AI驱动办公可视化智能工具,一键高效生成文档图表脑图
    可赞AI
    可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
    3685次使用
  • 星月写作:AI网文创作神器,助力爆款小说速成
    星月写作
    星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
    4820次使用
  • MagicLight.ai:叙事驱动AI动画视频创作平台 | 高效生成专业级故事动画
    MagicLight
    MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
    4048次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码