파이썬 json.loads는 ValueError : Extra data를 보여줍니다


151

JSON 파일 "new.json"에서 일부 데이터를 가져오고 일부 데이터를 필터링하여 새 JSON 파일에 저장하려고합니다. 내 코드는 다음과 같습니다.

import json
with open('new.json') as infile:
    data = json.load(infile)
for item in data:
    iden = item.get["id"]
    a = item.get["a"]
    b = item.get["b"]
    c = item.get["c"]
    if c == 'XYZ' or  "XYZ" in data["text"]:
        filename = 'abc.json'
    try:
        outfile = open(filename,'ab')
    except:
        outfile = open(filename,'wb')
    obj_json={}
    obj_json["ID"] = iden
    obj_json["VAL_A"] = a
    obj_json["VAL_B"] = b

오류가 발생했습니다. 추적은 다음과 같습니다.

  File "rtfav.py", line 3, in <module>
    data = json.load(infile)
  File "/usr/lib64/python2.7/json/__init__.py", line 278, in load
    **kw)
  File "/usr/lib64/python2.7/json/__init__.py", line 326, in loads
    return _default_decoder.decode(s)
  File "/usr/lib64/python2.7/json/decoder.py", line 369, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 88 column 2 - line 50607 column 2 (char 3077 - 1868399)

누군가 나를 도울 수 있습니까?

다음은 new.json의 데이터 샘플입니다. 파일에 약 1500 개 이상의 사전이 있습니다.

{
    "contributors": null, 
    "truncated": false, 
    "text": "@HomeShop18 #DreamJob to professional rafter", 
    "in_reply_to_status_id": null, 
    "id": 421584490452893696, 
    "favorite_count": 0, 
    "source": "<a href=\"https://mobile.twitter.com\" rel=\"nofollow\">Mobile Web (M2)</a>", 
    "retweeted": false, 
    "coordinates": null, 
    "entities": {
        "symbols": [], 
        "user_mentions": [
            {
                "id": 183093247, 
                "indices": [
                    0, 
                    11
                ], 
                "id_str": "183093247", 
                "screen_name": "HomeShop18", 
                "name": "HomeShop18"
            }
        ], 
        "hashtags": [
            {
                "indices": [
                    12, 
                    21
                ], 
                "text": "DreamJob"
            }
        ], 
        "urls": []
    }, 
    "in_reply_to_screen_name": "HomeShop18", 
    "id_str": "421584490452893696", 
    "retweet_count": 0, 
    "in_reply_to_user_id": 183093247, 
    "favorited": false, 
    "user": {
        "follow_request_sent": null, 
        "profile_use_background_image": true, 
        "default_profile_image": false, 
        "id": 2254546045, 
        "verified": false, 
        "profile_image_url_https": "https://pbs.twimg.com/profile_images/413952088880594944/rcdr59OY_normal.jpeg", 
        "profile_sidebar_fill_color": "171106", 
        "profile_text_color": "8A7302", 
        "followers_count": 87, 
        "profile_sidebar_border_color": "BCB302", 
        "id_str": "2254546045", 
        "profile_background_color": "0F0A02", 
        "listed_count": 1, 
        "profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png", 
        "utc_offset": null, 
        "statuses_count": 9793, 
        "description": "Rafter. Rafting is what I do. Me aur mera Tablet.  Technocrat of Future", 
        "friends_count": 231, 
        "location": "", 
        "profile_link_color": "473623", 
        "profile_image_url": "http://pbs.twimg.com/profile_images/413952088880594944/rcdr59OY_normal.jpeg", 
        "following": null, 
        "geo_enabled": false, 
        "profile_banner_url": "https://pbs.twimg.com/profile_banners/2254546045/1388065343", 
        "profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png", 
        "name": "Jayy", 
        "lang": "en", 
        "profile_background_tile": false, 
        "favourites_count": 41, 
        "screen_name": "JzayyPsingh", 
        "notifications": null, 
        "url": null, 
        "created_at": "Fri Dec 20 05:46:00 +0000 2013", 
        "contributors_enabled": false, 
        "time_zone": null, 
        "protected": false, 
        "default_profile": false, 
        "is_translator": false
    }, 
    "geo": null, 
    "in_reply_to_user_id_str": "183093247", 
    "lang": "en", 
    "created_at": "Fri Jan 10 10:09:09 +0000 2014", 
    "filter_level": "medium", 
    "in_reply_to_status_id_str": null, 
    "place": null
} 

이것은 입력 JSON에 한 줄에 둘 이상의 객체가있을 때마다 발생하는 오류입니다. 여기서 많은 대답은 한 줄에 하나의 객체 만 있다고 가정하거나 그에 따르는 예제를 구성하지만 그렇지 않은 경우 중단됩니다.
smci

@smci : 당신은 라인을 설명 할 수more than one object per line
aspiring1

답변:


150

다음 예제에서 볼 수 있듯이 json.loads(및 json.load)은 여러 json 객체를 디코딩하지 않습니다.

>>> json.loads('{}')
{}
>>> json.loads('{}{}') # == json.loads(json.dumps({}) + json.dumps({}))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python27\lib\json\__init__.py", line 338, in loads
    return _default_decoder.decode(s)
  File "C:\Python27\lib\json\decoder.py", line 368, in decode
    raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 1 column 3 - line 1 column 5 (char 2 - 4)

여러 사전을 덤프하려면 목록으로 랩핑하고 사전을 여러 번 덤프하는 대신 목록을 덤프하십시오.

>>> dict1 = {}
>>> dict2 = {}
>>> json.dumps([dict1, dict2])
'[{}, {}]'
>>> json.loads(json.dumps([dict1, dict2]))
[{}, {}]

7
위에서 제공 한 코드를 참조하여 다시 설명해 주시겠습니까? 나는 초보자이며, 때로는 그런 것들을 이해하는 데 시간이 오래 걸립니다.
Apoorv Ashutosh

1
@ ApoorvAshutosh, new.jsonjson과 다른 중복 데이터가 포함되어있는 것 같습니다 . json.load, json.loads단지 JSON을 디코딩 할 수있다. 그것은 인상 ValueError당신이 보는대로 addtional 데이터가 발생할 때.
falsetru

new.json에서 샘플을 붙여 넣었고 일부 데이터를 필터링하므로 추가 데이터를 어디에서 얻지 못합니다.
Apoorv Ashutosh

1
@ ApoorvAshutosh, 당신은 편집 된 질문에 1500 더 많은 사전 을 말했다 . 추가 데이터입니다. 당신이 만든 하나의 경우 new.json, 단지 파일에 하나의 JSON을 넣어.
falsetru

1
@ApoorvAshutosh, 여러 사전을 json으로 덤프해야하는 경우 목록으로 랩핑하고 목록을 덤프하십시오.
falsetru

100

jsonifying각 줄마다 파일에서 읽을 수 있습니다 .

tweets = []
for line in open('tweets.json', 'r'):
    tweets.append(json.loads(line))

이것은 중간 파이썬 객체를 저장하지 않습니다. append()통화 당 하나의 전체 트윗을 작성하는 한 , 이것이 작동합니다.


7
허용되는 답변은 내보내기 프로세스를 제어하는 ​​경우 문제의 원인을 해결하는 방법을 설명하지만 다른 사람의 데이터를 사용하고 있고 처리해야하는 경우 오버 헤드가 적은 훌륭한 방법입니다.
charlesreid1

3
요즘 많은 데이터 세트 (예 : Yelp 데이터 세트)가 Json 객체의 "세트"로 제공되며 사용자의 접근 방식은로드하는 것이 편리합니다.
Gabrer

36

MongoDB에서 덤프 된 JSON 파일을로드하려고했기 때문에이 문제가 발생했습니다. 그것은 나에게 오류를주고 있었다

JSONDecodeError: Extra data: line 2 column 1

MongoDB JSON 덤프에는 한 줄에 하나의 객체가 있으므로 나를 위해 일한 것은 다음과 같습니다.

import json
data = [json.loads(line) for line in open('data.json', 'r')]

13

JSON 파일이 1 개의 JSON 레코드가 아닌 경우에도 발생할 수 있습니다. JSON 레코드는 다음과 같습니다.

[{"some data": value, "next key": "another value"}]

괄호 안에 중괄호 {}가 포함되어 있고 대괄호 []로 열리고 닫힙니다. 괄호 쌍은 여러 개가있을 수 있지만 모두 괄호로 끝납니다]. json 파일에 둘 이상의 파일이 포함 된 경우 :

[{"some data": value, "next key": "another value"}]
[{"2nd record data": value, "2nd record key": "another value"}]

그러면 loads ()가 실패합니다.

나는 실패한 내 자신의 파일로 이것을 확인했다.

import json

guestFile = open("1_guests.json",'r')
guestData = guestFile.read()
guestFile.close()
gdfJson = json.loads(guestData)

1_guests.json에 하나의 레코드 []가 있기 때문에 작동합니다. all_guests.json을 사용하고 있던 원래 파일에는 줄 바꿈으로 구분 된 6 개의 레코드가있었습니다. 5 개의 레코드 (이미 괄호로 묶은 것으로 확인 됨)를 삭제하고 파일을 새 이름으로 저장했습니다. 그런 다음 loads 문이 작동했습니다.

오류

   raise ValueError(errmsg("Extra data", s, end, len(s)))
ValueError: Extra data: line 2 column 1 - line 10 column 1 (char 261900 - 6964758)

추신. 나는 단어 기록을 사용하지만 공식 이름은 아닙니다. 또한 파일에 내 줄 바꿈 문자가있는 경우 한 번에 하나의 레코드를 json 변수에로드하기 위해 파일을 반복 할 수 있습니다.


2
json.loads줄 바꿈으로 구분 된 JSON 청크를 읽는 방법이 있습니까? 즉,처럼 행동 [json.loads(x) for x in text.split('\n')]? 관련 : json.dumps기본 들여 쓰기로 출력에 리터럴 줄 바꿈이 포함되지 않는다는 보장이 있습니까?
Ben

1
@Ben은 기본적 json.dumps으로 텍스트 내용의 개행을로 변경 "\n"하여 json을 한 줄로 유지합니다.
jchook

7

글쎄, 그것은 누군가를 도울 수 있습니다. 내 json 파일이 이와 같은 동안 방금 동일한 오류가 발생했습니다.

{"id":"1101010","city_id":"1101","name":"TEUPAH SELATAN"}
{"id":"1101020","city_id":"1101","name":"SIMEULUE TIMUR"}

나는 그것이 잘못되었다는 것을 알았습니다. 그래서 나는 그것을

{
  "datas":[
    {"id":"1101010","city_id":"1101","name":"TEUPAH SELATAN"},
    {"id":"1101020","city_id":"1101","name":"SIMEULUE TIMUR"}
  ]
}

1
단지 당신처럼로드, json.load (INFILE)
아크 바르 노토

6

당신의 문제를위한 1 개의 강선 :

data = [json.loads(line) for line in open('tweets.json', 'r')]

1
이것은 일반적인 해결책이 아니며 입력에 한 줄에 하나의 JSON 객체가 있다고 가정하고 그렇지 않은 경우 중단합니다.
smci

3

2 라이너로 해결하려면 다음과 같이하십시오.

with open('data.json') as f:
    data = [json.loads(line) for line in f]

1

나는 목록에 dicts를 저장하는 것이 @falsetru가 제안한 이상적인 솔루션이 아니라고 생각합니다.

더 좋은 방법은 dicts를 반복하고 새 줄을 추가하여 .json에 저장하는 것입니다.

우리의 두 사전은

d1 = {'a':1}

d2 = {'b':2}

.json에 쓸 수 있습니다

import json
with open('sample.json','a') as sample:
    for dict in [d1,d2]:
        sample.write('{}\n'.format(json.dumps(dict)))

그리고 당신은 아무런 문제없이 json 파일을 읽을 수 있습니다

with open('sample.json','r') as sample:
    for line in sample:
        line = json.loads(line.strip())

간단하고 효율적인


이것은 일반적인 해결책이 아니며 입력에 한 줄에 하나의 JSON 객체가 있다고 가정하고 그렇지 않은 경우 중단합니다.
smci
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.