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格式不正确的问题
你把 response 打印出来不就能知道 json 哪里不对了。。
遇到JSON格式不正确的问题,通常是因为字符串不符合JSON规范。最常见的情况是使用了单引号、存在未转义的特殊字符,或者字符串本身就不是有效的JSON。
首先,你得确认错误的具体原因。Python的json模块在解析时会抛出明确的异常,比如json.JSONDecodeError,它会告诉你错误位置和类型。
处理步骤:
- 捕获异常:使用
try-except块来捕获json.JSONDecodeError。 - 检查常见问题:
- 单引号问题:JSON标准要求使用双引号。如果你处理的字符串用了单引号,可以用
str.replace()简单替换,但这种方法不严谨,对于复杂嵌套或字符串内容本身包含引号的情况会出错。更可靠的方法是使用ast.literal_eval()(但仅适用于Python字面量,且需注意安全性)。 - 特殊字符未转义:比如字符串中的换行符
\n、制表符\t或引号本身。确保它们在字符串中被正确转义(例如\")。 - 编码问题:如果JSON字符串是从文件或网络读取的,确保使用正确的编码(如
utf-8)打开。 - 尾随逗号:JSON不支持对象或数组最后一个元素后的逗号。
- 使用在线验证器:将你的JSON字符串粘贴到在线JSON验证器(如jsonlint.com)可以快速定位语法错误。
- 单引号问题:JSON标准要求使用双引号。如果你处理的字符串用了单引号,可以用
代码示例:
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 或其他的数据
我在想你的学习计划是不是安排得有问题,拧螺丝都没拧熟就准备开始造火箭啦?
没办法,都说看了基础,开始做程序,我就看看别人的源码,然后慢慢来呗。

