Python中如何解决JSON格式不正确的问题

学习 python,用的一个源代码:

https://github.com/rollingstarky/Python-Voice-Assistant/blob/master/src/ai.py

就是录音+百度识别+图灵

这个代码有点老了,我这里运行的错误提示如下:

please say something
you said: 你好
Traceback (most recent call last):
  File "aitalk.py", line 129, in <module>
    response = robot(request)
  File "aitalk.py", line 78, in robot
    response_dict = json.loads(response.text)
  File "/Users/v2ex/.pyenv/versions/3.6.0/lib/python3.6/json/__init__.py", line 354, in loads
    return _default_decoder.decode(s)
  File "/Users/v2ex/.pyenv/versions/3.6.0/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/Users/v2ex.pyenv/versions/3.6.0/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

请教应该怎么修改啊??


Python中如何解决JSON格式不正确的问题

8 回复

你把 response 打印出来不就能知道 json 哪里不对了。。


遇到JSON格式不正确的问题,通常是因为字符串不符合JSON规范。最常见的情况是使用了单引号、存在未转义的特殊字符,或者字符串本身就不是有效的JSON。

首先,你得确认错误的具体原因。Python的json模块在解析时会抛出明确的异常,比如json.JSONDecodeError,它会告诉你错误位置和类型。

处理步骤:

  1. 捕获异常:使用try-except块来捕获json.JSONDecodeError
  2. 检查常见问题
    • 单引号问题:JSON标准要求使用双引号。如果你处理的字符串用了单引号,可以用str.replace()简单替换,但这种方法不严谨,对于复杂嵌套或字符串内容本身包含引号的情况会出错。更可靠的方法是使用ast.literal_eval()(但仅适用于Python字面量,且需注意安全性)。
    • 特殊字符未转义:比如字符串中的换行符\n、制表符\t或引号本身。确保它们在字符串中被正确转义(例如\")。
    • 编码问题:如果JSON字符串是从文件或网络读取的,确保使用正确的编码(如utf-8)打开。
    • 尾随逗号:JSON不支持对象或数组最后一个元素后的逗号。
    • 使用在线验证器:将你的JSON字符串粘贴到在线JSON验证器(如jsonlint.com)可以快速定位语法错误。

代码示例:

import json
import ast

def parse_json_safely(json_string):
    """
    尝试解析JSON字符串,如果失败,尝试修复常见的单引号问题。
    注意:ast.literal_eval 可以处理Python字面量,但需确保输入来源可信。
    """
    try:
        # 标准解析
        return json.loads(json_string)
    except json.JSONDecodeError as e:
        print(f"标准解析失败: {e}")
        try:
            # 尝试处理单引号:用双引号替换单引号,但需小心处理字符串内的引号
            # 更健壮的做法是使用 ast.literal_eval
            fixed_string = json_string.replace("'", '"')
            return json.loads(fixed_string)
        except json.JSONDecodeError:
            print("替换引号后仍失败。")
        try:
            # 使用 ast.literal_eval 处理Python风格的字典/列表字符串(如"{'key': 'value'}")
            # 警告:仅对可信输入使用,因为它可以执行任意代码。
            return ast.literal_eval(json_string)
        except (SyntaxError, ValueError) as e:
            print(f"ast.literal_eval 也失败了: {e}")
            return None

# 测试用例
test_cases = [
    '{"name": "Alice", "age": 30}',  # 标准JSON
    "{'name': 'Bob', 'age': 25}",    # 单引号(非标准)
    '{"text": "It\'s a test"}',      # 字符串内包含单引号(已转义)
    '{"list": [1, 2, 3,]}',          # 尾随逗号(无效JSON)
]

for i, test in enumerate(test_cases):
    print(f"\n测试用例 {i+1}: {test[:50]}...")
    result = parse_json_safely(test)
    print(f"解析结果: {result}")

总结建议: 优先使用json.loads()并捕获异常,用在线验证器检查原始字符串,对于简单的单引号问题可尝试ast.literal_eval(注意安全)。

这个代码怎么这么奇怪? requests 有 .post() 的方法,还用 request(‘POST’, …)。requests 有 res.json() 的方法,还用 json.loads()。

水平不行呗.
请求 api 完全不判断一下能否返回结果啊.
我 request 之后都会 try 一下.


result = response_dict[“results”][0][“values”][“text”]
还有这个,万一 dict 没有 results 怎么办?

看看作者在不在这里。。。。。

一般情况是第 78 行的时候发生了错误,导致返回的内容已经不是 json,变成了 html 或其他的数据

我在想你的学习计划是不是安排得有问题,拧螺丝都没拧熟就准备开始造火箭啦?

没办法,都说看了基础,开始做程序,我就看看别人的源码,然后慢慢来呗。

回到顶部