【问题标题】:JSON ValueError: Expecting property name: line 1 column 2 (char 1)JSON ValueError:期望属性名称:第 1 行第 2 列(字符 1)
【发布时间】:2014-10-31 16:29:14
【问题描述】:

我在使用 json.loads 转换为 dict 对象时遇到问题,我无法弄清楚我做错了什么。我运行它的确切错误是

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})

但我不知道该怎么做才能修复它。任何建议将不胜感激。

【问题讨论】:

  • 您在那里看到语法错误吗?一个流浪"是复制粘贴错误吗?
  • print tweet.message.value 行打印出的 JSON 字符串是什么?
  • ValueError 发送是因为 JSON 输入中的错误,而不是您的代码中的问题。 (除了缺少的",他通常应该发送SyntaxError,所以我认为这只是一个复制粘贴错误。)
  • (顺便说一句,utf_8 是 json.loads 的默认编码,所以不需要指明。)
  • 感谢您的意见。编辑了问题,现在应该更清楚了。

标签: python json pymongo


【解决方案1】:

json.loads 会将 json 字符串加载到 python dictjson.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 string 应该有 <type 'str'>

因此,如果您尝试加载 json,则应将加载的内容更改为类似于上面的 json_string,或者您应该转储它。这只是我从给定信息中的最佳猜测。你想达到什么目的?

你也不需要在你的字符串之前指定u,就像在cmets中提到的@Cld。

【讨论】:

  • json.loads 会将 -->json 对象 -- 这与文档所说的甚至与您自己的代码所做的相反--您在字符串上使用loads(),而不是json object.
  • 是的@7stud,你是对的,它正在加载一个字符串。但它必须是有效的 json 字符串。我已经更新了我的答案。
【解决方案2】:

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

单引号问题

我使用了带有 单引号的 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 将通过像Python 字典一样插入JSON 来防止单引号和逗号问题(因此您必须遵循Python 字典语法)。对于文字结构,它是 eval() 函数的一个很好且安全的替代方案。

Python documentation 警告我们使用大/复杂的字符串:

警告 Python 解释器可能会崩溃 由于堆栈深度限制,足够大/复杂的字符串 Python 的 AST 编译器。

json.dumps 带单引号

要轻松使用带单引号的json.dumps,您可以使用以下代码:

import ast
import json

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

ast 文档

ast Python 3 doc

ast Python 2 doc

工具

如果你经常编辑 JSON,你可以使用CodeBeautify。它可以帮助您修复语法错误并缩小/美化 JSON。

希望对你有帮助。

【讨论】:

    【解决方案3】:
    1. 用双引号替换所有单引号
    2. 将字符串中的 'u"' 替换为 '"' ...所以基本上在将字符串加载到 json 之前将内部 unicode 转换为字符串
    >> strs = "{u'key':u'val'}"
    >> strs = strs.replace("'",'"')
    >> json.loads(strs.replace('u"','"'))
    

    【讨论】:

    • 更 Python 的方式是使用 ast.literal_eval("{u'key':u'val'}")。它将处理所有与格式相关的问题
    • json.loads(strs.replace('u"','')) 不起作用。这是以下错误,Traceback(最近一次调用最后一次):文件“”,第 1 行,在 文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py”中,第 338 行,加载返回 _default_decoder.decode(s) obj , end = self.scan_once(s, idx) ValueError: Expecting property name: line 1 column 2 (char 1)
    【解决方案4】:

    所有其他答案可能会回答您的查询,但我遇到了同样的问题,这是由于我在 json 字符串末尾添加的流浪 , 造成的,如下所示:

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

    当我像这样删除额外的, 时,我终于让它工作了:

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

    希望对您有所帮助!干杯。

    【讨论】:

    【解决方案5】:

    用过的, 例子

    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'}]
    

    【讨论】:

      【解决方案6】:

      我遇到这种情况的另一种情况是,当我使用echo 将 JSON 传递到我的 python 脚本中并且不小心将 JSON 字符串包裹在双引号中时:

      echo "{"thumbnailWidth": 640}" | myscript.py
      

      请注意,JSON 字符串本身有引号,我应该这样做:

      echo '{"thumbnailWidth": 640}' | myscript.py
      

      事实上,这是 python 脚本收到的内容:{thumbnailWidth: 640};双引号被有效地去除了。

      【讨论】:

        猜你喜欢
        • 2014-12-02
        • 2018-06-28
        • 1970-01-01
        • 1970-01-01
        • 2019-05-27
        • 1970-01-01
        • 2018-10-30
        • 2020-02-03
        • 2021-12-31
        相关资源
        最近更新 更多