JSON值错误:期待属性名:第1行第2列(字符1)

103 投票
6 回答
265493 浏览
提问于 2025-04-20 06:01

我在使用json.loads把数据转换成字典对象时遇到了麻烦,搞不清楚自己哪里出错了。运行这段代码时出现的具体错误是:

ValueError: Expecting property name: line 1 column 2 (char 1)

这是我的代码:

from kafka.client import KafkaClient
from kafka.consumer import SimpleConsumer
from kafka.producer import SimpleProducer, KeyedProducer
import pymongo
from pymongo import MongoClient
import json

c = MongoClient("54.210.157.57")
db = c.test_database3
collection = db.tweet_col

kafka = KafkaClient("54.210.157.57:9092")

consumer = SimpleConsumer(kafka,"myconsumer","test")
for tweet in consumer:
    print tweet.message.value
    jsonTweet=json.loads(({u'favorited': False, u'contributors': None})
    collection.insert(jsonTweet)

我很确定错误发生在倒数第二行

jsonTweet=json.loads({u'favorited': False, u'contributors': None})

但我不知道该怎么修复它。任何建议都非常感谢。

6 个回答

0

使用了ast,下面是一个例子:

In [15]: a = "[{'start_city': '1', 'end_city': 'aaa', 'number': 1},\
...:      {'start_city': '2', 'end_city': 'bbb', 'number': 1},\
...:      {'start_city': '3', 'end_city': 'ccc', 'number': 1}]"
In [16]: import ast
In [17]: ast.literal_eval(a)
Out[17]:
[{'end_city': 'aaa', 'number': 1, 'start_city': '1'},
 {'end_city': 'bbb', 'number': 1, 'start_city': '2'},
 {'end_city': 'ccc', 'number': 1, 'start_city': '3'}]
4

其他的回答可能都能解决你的问题,但我遇到的情况是因为我在我的json字符串的末尾多加了一个,,像这样:

{
 "key":"123sdf",
 "bus_number":"asd234sdf",
}

我在去掉那个多余的,后,终于让它正常工作了,像这样:

{
 "key":"123sdf",
 "bus_number":"asd234sdf"
}

希望这能帮到你!加油。

11
  1. 把所有的单引号换成双引号。
  2. 把你的字符串中的 'u"' 替换成 '"' ... 也就是说,在把字符串加载到 JSON 之前,先把里面的 Unicode 转换成字符串。
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))
208

我遇到了另一个问题,返回了相同的错误。

单引号问题

我使用了一个包含单引号的json字符串:

{
    'property': 1
}

但是json.loads只接受双引号作为json属性

{
    "property": 1
}

最后一个逗号问题

json.loads不接受最后的逗号:

{
  "property": "text", 
  "property2": "text2",
}

解决方案:使用ast解决单引号和最后逗号问题

你可以使用ast(这是Python 2和3的标准库的一部分)来处理这个问题。下面是一个例子:

import ast
# ast.literal_eval() return a dict object, we must use json.dumps to get JSON string
import json

# Single quote to double with ast.literal_eval()
json_data = "{'property': 'text'}"
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property": "text"}

# ast.literal_eval() with double quotes
json_data = '{"property": "text"}'
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property": "text"}

# ast.literal_eval() with final coma
json_data = "{'property': 'text', 'property2': 'text2',}"
json_data = ast.literal_eval(json_data)
print(json.dumps(json_data))
# Displays : {"property2": "text2", "property": "text"}

使用ast可以避免单引号和最后逗号的问题,因为它会把JSON当作Python字典来解释(所以你必须遵循Python字典的语法)。这是一种相对安全且不错的替代方案,类似于eval()函数,但更适合处理字面量结构。

Python文档提醒我们使用大型或复杂字符串时要小心:

警告:由于Python的AST编译器在栈深度上的限制,使用足够大或复杂的字符串可能会导致Python解释器崩溃。

使用单引号的json.dumps

如果你想轻松地使用json.dumps和单引号,可以使用以下代码:

import ast
import json

data = json.dumps(ast.literal_eval(json_data_single_quote))

ast文档

ast Python 3文档

ast Python 2文档

工具

如果你经常编辑JSON,可以使用CodeBeautify。它可以帮助你修复语法错误,并对JSON进行压缩或美化。

87

json.loads 是用来把一个 json 字符串转换成 Python 的 dict(字典),而 json.dumps 则是把一个 Python 的 dict 转换成 json 字符串。例如:

>>> json_string = '{"favorited": false, "contributors": null}'
'{"favorited": false, "contributors": null}'
>>> value = json.loads(json_string)
{u'favorited': False, u'contributors': None}
>>> json_dump = json.dumps(value)
'{"favorited": false, "contributors": null}'

所以那一行是错误的,因为你试图 load 一个 Python 的 dict,而 json.loads 其实是期待一个有效的 json 字符串,这个字符串应该是 <type 'str'> 类型。

所以如果你想加载 json,你需要把你要加载的内容改成上面那个 json_string 的样子,或者你应该使用 dumps 来转换。这只是我根据提供的信息做的最佳猜测。你到底想要实现什么呢?

另外,你不需要在字符串前面加 u,正如 @Cld 在评论中提到的那样。

撰写回答