JSON ValueError: การคาดหวังชื่อคุณสมบัติ: บรรทัด 1 คอลัมน์ 2 (ถ่าน 1)


97

ฉันมีปัญหาในการใช้ 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)

ฉันค่อนข้างมั่นใจว่าเกิดข้อผิดพลาดที่บรรทัดที่ 2 ถึงสุดท้าย

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

แต่ฉันไม่รู้ว่าจะต้องทำอย่างไรเพื่อแก้ไข คำแนะนำใด ๆ ที่จะได้รับการชื่นชม.


3
คุณเห็นข้อผิดพลาดทางไวยากรณ์หรือไม่ หลงทาง"คือข้อผิดพลาดในการคัดลอกวางหรือไม่?
karthikr

สตริง JSON พิมพ์ออกมาทางบรรทัดprint tweet.message.valueอะไร
Luke Woodward

1
ValueErrorคือการส่งเนื่องจากข้อผิดพลาดในการป้อนข้อมูล JSON, ไม่ได้เป็นปัญหาในรหัสของคุณ (ข้างๆผู้สูญหาย"ที่ปกติควรส่งSyntaxErrorดังนั้นฉันถือว่าเป็นเพียงข้อผิดพลาดในการคัดลอกวาง)
Cld

(อย่างไรก็ตาม utf_8 เป็นการเข้ารหัสเริ่มต้นสำหรับ json.loads ดังนั้นจึงไม่จำเป็นต้องระบุ)
Cld

ขอบคุณสำหรับข้อมูล แก้ไขคำถามน่าจะชัดเจนกว่านี้
ขุดลอก

คำตอบ:


84

json.loadsจะโหลดสตริง JSON เข้าหลามdict, json.dumpsจะถ่ายโอนหลาม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หลามdictและjson.loadsคาดว่าที่ถูกต้องที่ควรจะมีjson string<type 'str'>

ดังนั้นหากคุณกำลังพยายามโหลด json คุณควรเปลี่ยนสิ่งที่คุณกำลังโหลดให้มีลักษณะเหมือนjson_stringข้างบนหรือคุณควรจะทิ้งมัน นี่เป็นเพียงการคาดเดาที่ดีที่สุดของฉันจากข้อมูลที่ระบุ อะไรคือสิ่งที่คุณพยายามทำให้สำเร็จ?

นอกจากนี้คุณไม่จำเป็นต้องระบุuก่อนสตริงของคุณตามที่ @Cld กล่าวถึงในความคิดเห็น


2
json.loads จะโหลดอ็อบเจกต์ -> json <- ลงใน python dict - นั่นตรงกันข้ามกับสิ่งที่เอกสารพูดและแม้แต่โค้ดของคุณเองก็ตาม - คุณกำลังใช้ load () บนสตริงไม่ใช่json วัตถุ
7stud

ใช่ @ 7stud คุณถูกต้องกำลังโหลดสตริง แต่ต้องเป็นสตริง json ที่ถูกต้อง ฉันได้อัปเดตคำตอบแล้ว
Yep_It's_Me

191

ฉันพบปัญหาอื่นที่ส่งกลับข้อผิดพลาดเดียวกัน

ปัญหาใบเสนอราคาเดียว

ฉันใช้สตริง 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 dictionnary) เป็นทางเลือกที่ดีและปลอดภัย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 doc

ast Python 2 doc

เครื่องมือ

หากคุณมักแก้ไข JSON คุณอาจใช้CodeBeautify ช่วยให้คุณแก้ไขข้อผิดพลาดทางไวยากรณ์และลดขนาด / สวยงาม JSON

ฉันหวังว่ามันจะช่วยได้


10
  1. แทนที่คำพูดเดี่ยวทั้งหมดด้วยเครื่องหมายคำพูดคู่
  2. แทนที่ 'u "' จากสตริงของคุณเป็น '"' ... โดยพื้นฐานแล้วจะแปลงยูนิโคดภายในเป็นสตริงก่อนที่จะโหลดสตริงลงใน json
>> strs = "{u'key':u'val'}"
>> strs = strs.replace("'",'"')
>> json.loads(strs.replace('u"','"'))

1
วิธี pythonic เพิ่มเติมคือการใช้ ast.literal_eval ("{u'key ': u'val'}") จะดูแลปัญหาที่เกี่ยวข้องกับรูปแบบทั้งหมด
Vinay Pande

json.loads (strs.replace ('u "', '')) ไม่ทำงานนี่คือข้อผิดพลาดด้านล่าง Traceback (โทรล่าสุดล่าสุด): ไฟล์" <stdin> "บรรทัด 1 ใน <module> ไฟล์ "/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: การคาดหวังชื่อคุณสมบัติ: บรรทัด 1 คอลัมน์ 2 (อักขระ 1)
Sanjay Pradeep

4

คำตอบอื่น ๆ ทั้งหมดอาจตอบคำถามของคุณ แต่ฉันประสบปัญหาเดียวกันซึ่งเกิดจากการหลงทาง,ซึ่งฉันได้เพิ่มไว้ที่ส่วนท้ายของสตริง json ของฉันเช่นนี้:

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

ในที่สุดฉันก็ใช้งานได้เมื่อฉันลบพิเศษ,เช่นนี้:

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

หวังว่านี่จะช่วยได้! ไชโย


1
สิ่งที่ดีแม้ว่าคำตอบของ jedema
fedorqui 'SO stop ทำร้าย'

@fedorqui ส่วนนั้นถูกเพิ่มหลังจากคำตอบของฉัน ( stackoverflow.com/posts/36599122/revisions ) ตอนนี้คุณอาจต้องการ +1 :)
Rishabh Agrahari

1
โอ้คุณพูดถูก! เพิ่มโดย ม.ค. 2018 ขอโทษและ +1 :)
fedorqui 'SO stop ทำร้าย'

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

0

อีกกรณีหนึ่งที่ฉันพบสิ่งนี้คือตอนที่ฉันใช้echoเพื่อไพพ์ JSON ลงในสคริปต์ python ของฉันและห่อสตริง JSON ด้วยเครื่องหมายอัญประกาศคู่อย่างไม่ระมัดระวัง:

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

โปรดทราบว่าสตริง JSON มีเครื่องหมายคำพูดและฉันควรทำ:

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

เหมือนเดิมนี่คือสิ่งที่สคริปต์ python ได้รับ: {thumbnailWidth: 640}; เครื่องหมายคำพูดคู่ถูกตัดออกอย่างมีประสิทธิภาพ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.