JSON ValueError: Đang mong đợi tên thuộc tính: dòng 1 cột 2 (ký tự 1)


97

Tôi đang gặp sự cố khi sử dụng json.loads để chuyển đổi thành đối tượng dict và tôi không thể tìm ra mình đang làm gì sai. Lỗi chính xác mà tôi gặp phải khi chạy cái này là

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

Đây là mã của tôi:

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)

Tôi khá chắc chắn rằng lỗi đang xảy ra ở dòng thứ 2 đến dòng cuối cùng

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

nhưng tôi không biết phải làm gì để sửa chữa nó. Lời khuyên nào sẽ được đánh giá cao.


3
bạn có thấy lỗi cú pháp ở đó không? Một đi lạc "là một bản sao dán lỗi?
karthikr

Chuỗi JSON được in ra bởi dòng print tweet.message.valuenào?
Luke Woodward

1
Các ValueErrorđược gửi bởi một lỗi trong đầu vào JSON, không phải là một vấn đề trong mã của bạn. (Bên cạnh người mất tích "thường gửi một, SyntaxErrorvì vậy tôi cho rằng đó chỉ là lỗi sao chép dán.)
Cld

(Nhân tiện, utf_8 là mã hóa mặc định cho json.loads nên không cần phải chỉ ra nó.)
Cld

Cảm ơn các đầu vào. Đã chỉnh sửa câu hỏi, nên rõ ràng hơn bây giờ.
nạo vét

Câu trả lời:


83

json.loadssẽ tải một chuỗi json vào một con trăn dict, json.dumpssẽ kết xuất một con trăn dictvào một chuỗi json, ví dụ:

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

Vì vậy, dòng đó không chính xác vì bạn đang thử loadpython dictjson.loadsđang mong đợi một giá trị hợp lệ json stringnên có <type 'str'>.

Vì vậy, nếu bạn đang cố gắng tải json, bạn nên thay đổi những gì bạn đang tải để trông giống như json_stringtrên, hoặc bạn nên bán nó. Đây chỉ là dự đoán tốt nhất của tôi từ những thông tin đã cho. Bạn đang cố gắng hoàn thành điều gì?

Ngoài ra, bạn không cần chỉ định utrước chuỗi của mình, như @Cld đã đề cập trong các nhận xét.


2
json.loads sẽ tải một -> đối tượng json <- vào một python dict - Điều đó trái với những gì tài liệu nói và thậm chí những gì mã của riêng bạn thực hiện - bạn đang sử dụng load () trên một chuỗi, không phải json đối tượng .
7stud

Đúng @ 7stud, bạn nói đúng, nó đang tải một chuỗi. Nhưng nó phải là một chuỗi json hợp lệ. Tôi đã cập nhật câu trả lời của mình.
Yep_It's_Me

186

Tôi gặp phải một sự cố khác trả về cùng một lỗi.

Vấn đề báo giá đơn

Tôi đã sử dụng một chuỗi json với các dấu ngoặc kép :

{
    'property': 1
}

Nhưng json.loadschỉ chấp nhận dấu ngoặc kép cho các thuộc tính json :

{
    "property": 1
}

Vấn đề về dấu phẩy cuối cùng

json.loads không chấp nhận dấu phẩy cuối cùng:

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

Giải pháp: astđể giải quyết các vấn đề về dấu ngoặc kép và dấu phẩy cuối cùng

Bạn có thể sử dụng ast(một phần của thư viện chuẩn cho cả Python 2 và 3) để xử lý này. Đây là một ví dụ :

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

Việc sử dụng astsẽ ngăn bạn khỏi các vấn đề về dấu ngoặc kép và dấu phẩy cuối cùng bằng cách xen kẽ JSON giống như chuỗi phân đoạn Python (vì vậy bạn phải tuân theo cú pháp phân đoạn Python). Đó là một sự thay thế eval()chức năng khá tốt và an toàn cho các cấu trúc chữ.

Tài liệu Python đã cảnh báo chúng tôi về việc sử dụng chuỗi lớn / phức tạp:

Cảnh báo Có thể gặp sự cố trình thông dịch Python với một chuỗi đủ lớn / phức tạp do giới hạn độ sâu ngăn xếp trong trình biên dịch AST của Python.

json.dumps với một dấu ngoặc kép

Để sử dụng json.dumpsvới các dấu ngoặc kép dễ dàng, bạn có thể sử dụng mã này:

import ast
import json

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

ast tài liệu

ast Python 3 doc

ast Python 2 doc

Dụng cụ

Nếu bạn thường xuyên chỉnh sửa JSON, bạn có thể sử dụng CodeBeautify . Nó giúp bạn sửa lỗi cú pháp và thu nhỏ / làm đẹp JSON.

Tôi hy vọng nó sẽ giúp.


10
  1. thay thế tất cả các dấu ngoặc kép đơn bằng dấu ngoặc kép
  2. thay thế 'u "' từ chuỗi của bạn thành '"' ... vì vậy về cơ bản chuyển đổi các mã đơn nội bộ thành chuỗi trước khi tải chuỗi vào json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))

1
cách hay hơn sẽ là sử dụng ast.literal_eval ("{u'key ': u'val'}"). Nó sẽ chăm sóc của tất cả các vấn đề liên quan đến định dạng
Vinay Pande

json.loads (strs.replace ('u "', '')) không hoạt động. Đây là lỗi bên dưới, Traceback (lần gọi gần đây nhất): Tệp" <stdin> ", dòng 1, trong Tệp <module> "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", dòng 338, khi tải trả về _default_decoder.decode (s) obj, end = self.scan_once (s , idx) ValueError: Mong tên thuộc tính: dòng 1 cột 2 (char 1)
Sanjay Pradeep

4

Tất cả các câu trả lời khác có thể trả lời cho truy vấn của bạn, nhưng tôi gặp phải vấn đề tương tự do đi lạc ,mà tôi đã thêm vào cuối chuỗi json của mình như thế này:

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

Cuối cùng tôi đã làm cho nó hoạt động khi tôi loại bỏ thêm ,như thế này:

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

Hy vọng điều này giúp đỡ! hoan hô.


1
tốt nhất, mặc dù điều này đã được bao phủ bởi jedema của câu trả lời
fedorqui 'SO dừng hại'

@fedorqui phần đó đã được thêm vào sau khi câu trả lời của tôi ( stackoverflow.com/posts/36599122/revisions ) Bây giờ, bạn có thể muốn đưa ra một 1 :)
Rishabh Agrahari

1
oh, bạn đúng! Nó đã được thêm vào tháng 1 năm 2018. Xin lỗi và +1 :)
fedorqui 'VẬY đừng làm hại nữa'

0

đã sử dụng ast, ví dụ

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

0

Một trường hợp khác mà tôi gặp phải là khi tôi đang sử dụng echođể đưa JSON vào tập lệnh python của mình và bất cẩn quấn chuỗi JSON trong dấu ngoặc kép:

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

Lưu ý rằng bản thân chuỗi JSON có dấu ngoặc kép và tôi nên làm như sau:

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

Vì nó là, đây là những gì kịch bản python nhận: {thumbnailWidth: 640}; dấu ngoặc kép đã bị loại bỏ một cách hiệu quả.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.