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

调用json.loads解析MQTT消息时报JSONDecodeError: Extra data错误如何解决?

问题原因
  • 报错JSONDecodeError: Extra data的核心是待解析的字符串中,除了合法JSON内容外还存在多余字符。你单独复制打印的载荷可以正常解析,是因为logger输出时会自动过滤不可见字符,实际m_decode变量中包含打印不可见的冗余内容,最常见的是MQTT载荷末尾的空字节(\0)、换行符、回车符等控制字符,部分设备端发送MQTT消息时会主动添加这类结束标识,或者传输过程中出现了字符冗余。
  • 少数情况是单条MQTT消息中拼接了多条JSON报文,多个JSON对象连在一起也会触发该报错。
排查方法

在解码后先打印字符串的原始转义形式,确认是否存在冗余字符:

def on_message_mqtt(self, client, userdata, message):
    m_decode = message.payload.decode('utf-8')
    logger.info(repr(m_decode)) # 会把不可见字符转义为\x00、\n这类可见形式
    # 后续逻辑
解决方案

方案1:清洗首尾冗余字符(90%以上场景可用)

直接对解码后的字符串执行首尾去空白/控制符操作,默认会清除空字节、换行、回车、空格等冗余内容:

def on_message_mqtt(self, client, userdata, message):
    m_decode = message.payload.decode('utf-8').strip()
    logger.info(m_decode)
    m_in = json.loads(m_decode)
    logger.info(m_in)

方案2:提取合法JSON区间

如果冗余字符出现在JSON内容的前后位置,可以直接截取第一个{到最后一个}之间的内容解析:

def on_message_mqtt(self, client, userdata, message):
    m_decode = message.payload.decode('utf-8')
    start_idx = m_decode.find('{')
    end_idx = m_decode.rfind('}')
    if start_idx == -1 or end_idx == -1:
        logger.warning("收到的消息不包含合法JSON结构")
        return
    json_str = m_decode[start_idx: end_idx+1]
    m_in = json.loads(json_str)
    logger.info(m_in)

方案3:处理单条消息多条JSON的场景

如果确认是单条MQTT消息中拼接了多条JSON报文,可以用JSONDecoder的raw_decode方法逐段解析:

import json
def on_message_mqtt(self, client, userdata, message):
    m_decode = message.payload.decode('utf-8').strip()
    decoder = json.JSONDecoder()
    pos = 0
    while pos < len(m_decode):
        try:
            m_in, pos = decoder.raw_decode(m_decode, pos)
            logger.info(m_in) # 处理每条解析出来的JSON对象
        except json.JSONDecodeError as e:
            logger.error(f"解析失败,剩余内容: {m_decode[pos:]},错误: {e}")
            break

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 18:45:02