prosource

파이썬에서 JSON을 구문 분석(읽기)하고 사용하려면 어떻게 해야 합니까?

probook 2023. 5. 13. 10:19
반응형

파이썬에서 JSON을 구문 분석(읽기)하고 사용하려면 어떻게 해야 합니까?

내 파이썬 프로그램은 JSON 데이터를 수신하고, 나는 그것으로부터 약간의 정보를 얻어야 합니다.데이터를 구문 분석하고 결과를 사용하려면 어떻게 해야 합니까?제 생각에 저는 사용해야 할 것 같습니다.json.loads이 작업을 위해, 하지만 어떻게 해야 하는지 이해할 수 없습니다.

예를 들어, 제가 가지고 있다고 가정해 보세요.jsonStr = '{"one" : "1", "two" : "2", "three" : "3"}' JSON과 이할때의 , 그리고입력은려고을▁given은▁of입력,▁input그리▁this▁j고때▁an."two"어떻게 하면 해당 데이터를 얻을 수 있습니까?"2"?


해, 조심해요..load.loads현악기를 위한 것입니다.참고 항목: 파일에서 JSON 읽기.

JSON 문서가 표 형식의 데이터를 나타내는 경우도 있습니다.Pandas와 함께 사용하려는 경우 Python - JSON 파일을 Dataframe으로 변환하는 방법을 참조하십시오.

일부 데이터는 표면적으로는 JSON처럼 보이지만 JSON은 아닙니다.

예를 들어, 때때로 데이터는 적용에서 나옵니다.repr네이티브 Python 데이터 구조로 이동합니다.는 따옴표를 사용할 수 . 대소문자를 사용하십시오. 제목 대소문자를 사용하십시오.True그리고.False이 의무화한 JSON이 true그리고.false기타. 이러한 데이터는 사전의 문자열 표현을 사전으로 변환하거나 목록의 문자열 표현을 목록으로 변환하는 방법참조하십시오.

다른 일반적인 변형 형식은 입력의 각 줄에 유효한 JSON 형식의 데이터를 별도로 배치합니다. (적절한 JSON은 여러 줄 간격으로 균형이 잡힌 괄호를 사용하기 때문에 한 줄씩 구문 분석할 수 없습니다.)이 형식을 JSONL이라고 합니다. JSONL 파일을 JSON 개체로 로드를 참조하십시오.

때때로 웹 소스의 JSON 데이터는 추가 텍스트로 채워집니다.일부 컨텍스트에서는 브라우저의 보안 제한을 해결할 수 있습니다.이를 JSONP라고 하며 JSONP란 무엇이며, 만들어졌습니까?다른 맥락에서, 추가 텍스트는 (1); JSON 응답에 Google이 추가되는 이유에 설명된 대로 보안 조치를 구현합니다.어느 쪽이든 Python에서 이것을 처리하는 것은 간단합니다. 추가 텍스트를 식별하고 제거한 후 이전과 같이 진행하기만 하면 됩니다.

매우 간단합니다.

import json
data = json.loads('{"one" : "1", "two" : "2", "three" : "3"}')
print(data['two'])  # or `print data['two']` in Python 2

때때로 당신의 json은 현이 아닙니다.예를 들어 다음과 같은 URL에서 json을 가져오는 경우:

j = urllib2.urlopen('http://site.com/data.json')

json.load가 아닌 json.load를 사용해야 합니다.

j_obj = json.load(j)

(잊기 쉽습니다: 's'는 'string'을 의미합니다.

을 사용합니다.json.load() 내용이 포함된 .json 파일을 합니다.json.loads().

#! /usr/bin/python

import json
# from pprint import pprint

json_file = 'my_cube.json'
cube = '1'

with open(json_file) as json_data:
    data = json.load(json_data)

# pprint(data)

print "Dimension: ", data['cubes'][cube]['dim']
print "Measures:  ", data['cubes'][cube]['meas']

다음은 도움이 될 수 있는 간단한 예입니다.

json_string = """
{
    "pk": 1, 
    "fa": "cc.ee", 
    "fb": {
        "fc": "", 
        "fd_id": "12345"
    }
}"""

import json
data = json.loads(json_string)
if data["fa"] == "cc.ee":
    data["fb"]["new_key"] = "cc.ee was present!"

print json.dumps(data)

위 코드의 출력은 다음과 같습니다.

{"pk": 1, "fb": {"new_key": "cc.ee was present!", "fd_id": "12345", 
 "fc": ""}, "fa": "cc.ee"}

dump의 ident 인수를 설정하여 이렇게 인쇄할 수 있습니다(예: print json.dump(data, indent=4)를 사용하는 경우).

{
    "pk": 1, 
    "fb": {
        "new_key": "cc.ee was present!", 
        "fd_id": "12345", 
        "fc": ""
    }, 
    "fa": "cc.ee"
}

데이터 구문 분석

라이브러리 json 컨트롤 모듈

문자열 데이터의 경우 다음을 사용합니다.

import json

text = '{"one" : "1", "two" : "2", "three" : "3"}'
parsed = json.loads(example)

파일 또는 다른 파일 유사 개체에서 가져온 데이터의 경우 다음을 사용합니다.

import io, json
# create an in-memory file-like object for demonstration purposes.
text = '{"one" : "1", "two" : "2", "three" : "3"}'
stream = io.StringIO(text)
parsed = json.load(stream) # load, not loads

: 뒤에 것: 추적구다쉽니: 습별을.sloads는 " ( 하지 않을 것입니다 "string"과 "string" 사이에 있습니다. (이을인정대건, 아인표것않입다니맞현을지다대명관과준적니행명하합의)

:json.load 파일 경로를 허용하지 않습니다.

>>> json.load('example.txt')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/json/__init__.py", line 293, in load
    return loads(fp.read(),
AttributeError: 'str' object has no attribute 'read'

두 기능 모두 구문 분석 프로세스를 사용자 정의하기 위한 동일한 추가 옵션 집합을 제공합니다.3.6 이후에는 키워드만 선택할 수 있습니다.

문자열 데이터의 경우 다음과 같이 라이브러리에서 제공하는 클래스를 사용할 수도 있습니다.

import json
text = '{"one" : "1", "two" : "2", "three" : "3"}'
decoder = json.JSONDecoder()
parsed = decoder.decode(text)

동일한 키워드 매개 변수를 사용할 수 있지만 이제는 의 생성자에게 전달됩니다..decode방법.그 수업의 주요 장점은 또한 제공한다는 것입니다..raw_decodeJSON 종료 후 추가 데이터를 무시하는 메서드:

import json
text_with_junk = '{"one" : "1", "two" : "2", "three" : "3"} ignore this'
decoder = json.JSONDecoder()
# `amount` will count how many characters were parsed.
parsed, amount = decoder.raw_decode(text_with_junk)

용사를 합니다.requests 암묵적인 지원 ▁or.

있는 할 때requests라이브러리, 추출할 필요가 없습니다..text과 유사한.)Response반대하고 별도로 구문 분석합니다. 에신대,는,Response는 객가직제다니합공을 직접 합니다..json분석을 : " 구 분 수 할 메 서 드행이을문석:드메

import requests
response = requests.get('https://www.example.com')
parsed = response.json()

는 표준 이메는표준라리와동러키일허매변과 동일한 키워드 할 수 .json기능성

결과 사용

위의 방법 중 하나를 사용하여 구문 분석하면 기본적으로 완벽하게 일반적인 Python 데이터 구조가 생성되며, 이는 완벽하게 일반적인 내장형으로 구성됩니다. dict,list,str,int,float,bool(JSON)true그리고.false가 됨 Python 상수됨True그리고.False및 ) 및NoneType(JSON)null 파썬상가됨수가 .None).

따라서 이 결과를 사용하여 작업하면 다른 기술사용하여 동일한 데이터를 얻은 동일한 방식으로 작동합니다.

따라서 질문에서 예제를 계속하려면 다음과 같이 하십시오.

>>> parsed
{'one': '1', 'two': '2', 'three': '3'}
>>> parsed['two']
'2'

많은 사람들이 결과에 특별한 무언가가 있다고 기대하는 것처럼 보이기 때문에 제가 이것을 강조합니다.중첩을 처리하는 것은 때때로 이해하기 어렵지만, 중첩된 데이터 구조일 뿐입니다.

를 들어, 예를들어, ▁likesed오▁result▁consider보▁par시result = {'a': [{'b': 'c'}, {'d': 'e'}]} 위해.갖기 위해'e'를 한. 즉, 를 하십시오.a합니다.[{'b': 'c'}, {'d': 'e'}]의 두 그목색두요번소째인의록색(▁of요)▁the소인index1는 입니다.{'d': 'e'}그리고 그것을 찾아봅니다.'d'거기에 있는 열쇠는 줍니다.'e'value.값. 따서, 해코는입니다.result['a'][1]['d']각 인덱싱 단계가 순서대로 적용됩니다.

참고 항목내포된 데이터 구조(예: 구문 분석 JSON)에서 단일 값을 추출하려면 어떻게 해야 합니까?

때때로 사람들은 더 복잡한 선택 기준을 적용하고, 중첩된 목록 위에서 반복하고, 데이터를 필터링하거나 변환하는 등의 작업을 수행합니다.이것들은 다른 곳에서 다룰 더 복잡한 주제들입니다.

일반적인 혼동의 원인

JSON 닮았어요.

JSON 데이터를 구문 분석하기 전에 데이터가 실제로 JSON인지 확인하는 것이 중요합니다.JSON 형식 사양을 확인하여 예상되는 내용을 확인합니다.핵심 사항:

  • 문서는 하나의 값(일반적으로 파이썬에 해당하는 JSON "객체")을 나타냅니다.dict그러나 JSON으로 표시되는 다른 모든 유형은 허용됩니다.)특히, 각 라인에 별도의 엔트리가 없습니다. 즉, JSONL입니다.

  • 이 데이터는 표준 텍스트 인코딩(일반적으로 UTF-8)을 사용하면 사람이 읽을 수 있습니다.거의 모든 텍스트가 큰따옴표 에 포함되어 있으며, 적절한 경우 이스케이프 시퀀스를 사용합니다.

임베디드 데이터 처리

다음을 포함하는 예제 파일을 생각해 보십시오.

{"one": "{\"two\": \"three\", \"backslash\": \"\\\\\"}"}

여기 백슬래시는 JSON의 이스케이프 메커니즘을 위한 것입니다.위의 방법 중 하나로 구문 분석하면 다음과 같은 결과를 얻을 수 있습니다.

>>> example = input()
{"one": "{\"two\": \"three\", \"backslash\": \"\\\\\"}"}
>>> parsed = json.loads(example)
>>> parsed
{'one': '{"two": "three", "backslash": "\\\\"}'}

:parsed['one']a가 아니라 a입니다.dict그러나 이 문자열 자체는 "내장된" JSON 데이터를 나타냅니다.

내장된 데이터를 구문 분석된 결과로 바꾸려면 데이터에 액세스하고 동일한 구문 분석 기술을 사용한 다음 계속 진행합니다(예: 원래 결과를 대신 업데이트).

>>> parsed['one'] = json.loads(parsed['one'])
>>> parsed
{'one': {'two': 'three', 'backslash': '\\'}}

로 고는 다음과 .'\\'부분은 두 개가 아닌 하나의 실제 백슬래시를 포함하는 문자열을 나타냅니다.이것은 문자열 이스케이프에 대한 일반적인 파이썬 규칙을 따르고 있습니다. 그래서 우리는...

JSON 탈출 vs.Python 문자열 리터럴 이스케이프

때때로 사람들은 JSON 구문 분석을 포함하는 코드를 테스트하려고 할 때 혼란스러워하고 Python 소스 코드에서 잘못된 문자열 리터럴로 입력을 제공합니다.특히 임베디드 JSON과 함께 작동해야 하는 코드를 테스트할 때 발생합니다.

문제는 JSON 형식과 문자열 리터럴 형식이 각각 데이터 이스케이프를 위한 별도의 정책을 가지고 있다는 것입니다.Python은 문자열을 만들기 위해 문자열 리터럴에서 이스케이프를 처리할 것이며, 그 다음에도 JSON 형식에서 사용되는 이스케이프 시퀀스를 포함해야 합니다.

예에서 저는 위의예에, 사니다습했용서나를 했습니다.input탈출과 혼동을 피하기 위해 예제 데이터를 표시하는 인터프리터 프롬프트에서.다음은 소스에서 문자열 리터럴을 사용하는 유사한 예입니다.

>>> json.loads('{"one": "{\\"two\\": \\"three\\", \\"backslash\\": \\"\\\\\\\\\\"}"}')
{'one': '{"two": "three", "backslash": "\\\\"}'}

이중 따옴표로 묶인 문자열 리터럴을 대신 사용하려면 문자열 리터럴의 이중 따옴표도 이스케이프해야 합니다.따라서:

>>> json.loads('{\"one\": \"{\\\"two\\\": \\\"three\\\", \\\"backslash\\\": \\\"\\\\\\\\\\\"}\"}')
{'one': '{"two": "three", "backslash": "\\\\"}'}

스시퀀의 각 \\\"에서 입에서가 됩니다.\"실에JSON 터서이, 은과다같다습니가 됩니다."(문자열에 포함됨) JSON 파서에 의해 구문 분석될 때.유사하게,\\\\\\\\\\\"(의 백슬래시, 그 따옴표는 (5쌍의 백슬래시, 그다가인)가 됩니다\\\\\"에서 (하게 두 쌍의 따옴표), 이 값은 (5개의 백슬래시, 동하백게하, 두시와탈인)이 됩니다.\\" 두 와 따옴표)의해 될 때, (의 백슬래시와 ) JSON 파서가 됩니다.\\\\"구문 분석된 결과의 문자열 표현에서 (두 개의 이스케이프 백슬래시와 하나의 따옴표). 이제부터는 Python이 문자열에 단일 따옴표를 사용할 수 있으므로 따옴표를 이스케이프할 필요가 없지만 백슬래시는 여전히 사용할 수 있습니다.

간단한 사용자 지정

외에는strict 사션가키옵에 사용할 수 json.load그리고.json.loads콜백이어야 합니다.파서는 이들을 호출하여 데이터의 일부를 전달하고 반환되는 모든 것을 사용하여 전체 결과를 생성합니다.

"parse" 후크는 상당히 자명합니다.들어 을 예들 어부 소동값수다을점으로 할 수 .decimal.Decimal네이티브 파이썬을 사용하는 대신 인스턴스를 사용할 수 있습니다.float:

>>> import decimal
>>> json.loads('123.4', parse_float=decimal.Decimal)
Decimal('123.4')

또는 모든 값에 대해 float를 사용합니다. 대신 정수로 변환할 수 있는 경우에도 마찬가지입니다.

>>> json.loads('123', parse_int=float)
123.0

또는 특수 부동 소수점 값에 대한 JSON의 표현 변환을 거부합니다.

>>> def reject_special_floats(value):
...     raise ValueError
... 
>>> json.loads('Infinity')
inf
>>> json.loads('Infinity', parse_constant=reject_special_floats)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/json/__init__.py", line 370, in loads
    return cls(**kw).decode(s)
  File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.8/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
  File "<stdin>", line 2, in reject_special_floats
ValueError

사자지예를 사용한 정의 object_hook그리고.object_pairs_hook

object_hook그리고.object_pairs_hook 대신 JSON 가 주어졌을 때 하는 데 할 수 .dict된 A 공됨제object_pairs_hook됩니다. 으로, 그렇지 , 않사니됩용다음에면으그렇지수는인니로됩출-▁the,▁argument에 사용될 수 있습니다.dict원하는 값을 반환해야 합니다.dict또는 기타 결과:

>>> def process_object_pairs(items):
...     return {k: f'processed {v}' for k, v in items}
... 
>>> json.loads('{"one": 1, "two": 2}', object_pairs_hook=process_object_pairs)
{'one': 'processed 1', 'two': 'processed 2'}

된 A 공됨제object_hook 대다 음호함니다됩출께과신▁the다▁called▁with▁instead로 호출됩니다.dict그렇지 않으면 생성될 수 있으며 결과는 다음을 대체합니다.

>>> def make_items_list(obj):
...     return list(obj.items())
... 
>>> json.loads('{"one": 1, "two": 2}', object_hook=make_items_list)
[('one', 1), ('two', 2)]

둘 다 제공되는 경우,object_hook무시될 것이고 오직.object_items_hook사용됩니다.

및 텍스트 인코딩 문제bytes/unicode

JSON은 기본적으로 텍스트 형식입니다.입력 데이터는 파일을 구문 분석하기 전에 적절한 인코딩을 사용하여 원시 바이트에서 텍스트로 변환해야 합니다.

에서, 3.x에서 , 로위치bytes객체는 지원되며 암시적으로 UTF-8 인코딩을 사용합니다.

>>> json.loads('"text"')
'text'
>>> json.loads(b'"text"')
'text'
>>> json.loads('"\xff"') # Unicode code point 255
'ÿ'
>>> json.loads(b'"\xff"') # Not valid UTF-8 encoded data!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.8/json/__init__.py", line 343, in loads
    s = s.decode(detect_encoding(s), 'surrogatepass')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 1: invalid start byte

UTF-8은 일반적으로 JSON의 기본값으로 간주됩니다.원래 사양인 ECMA-404는 인코딩을 요구하지 않지만(JSON 파일이나 문서가 아닌 "JSON 텍스트"만 설명함) RFC 8259는 다음을 요구합니다.

폐쇄형 에코시스템의 일부가 아닌 시스템 간에 교환되는 JSON 텍스트는 UTF-8[RFC3629]을 사용하여 인코딩되어야 합니다.

이러한 "폐쇄 에코시스템"(예: 다르게 인코딩되어 공개적으로 공유되지 않을 로컬 문서의 경우)에서 먼저 적절한 인코딩을 명시적으로 적용합니다.

>>> json.loads(b'"\xff"'.decode('iso-8859-1'))
'ÿ'

마찬가지로 JSON 파일은 이진 모드가 아닌 텍스트 모드로 열어야 합니다.파일이 다른 인코딩을 사용하는 경우 파일을 열 때 다음과 같이 지정합니다.

with open('example.json', encoding='iso-8859-1') as f:
    print(json.load(f))

2.x에서는 문자열과 바이트 시퀀스가 제대로 구분되지 않아 특히 JSON으로 작업할 때 많은 문제와 혼란이 발생했습니다.

2.x 코드베이스를 적극적으로 유지 관리(2.x 자체는 2020년 1월 1일 이후로 유지 관리되지 않음)하는 것은 지속적으로 사용해야 합니다.unicode과 및를트텍나타는내값트스텍스▁to▁values값▁text는▁and.str 데이터를 나타내는 값)str는 의 별칭입니다.bytes2.x)에서, 그리고 그것을 받아들입니다.reprunicode값은 다음을 가질 것입니다.u접두사(결국 코드는 REP에서 보이는 값이 아니라 값이 실제로 무엇인지와 관련이 있어야 합니다).

노트: 기록노트:simplejson

simplejson 단순히 표준 라이브러리 모듈이지만 외부적으로 유지개발되었습니다.원래는 JSON 지원이 Python 표준 라이브러리에 추가되기 전에 만들어졌습니다.2.6에서는simplejson로 표준 라이브러리에 되었습니다.json현재 개발에서는 2.5 이전의 호환성을 유지하지만, 2.2 이전의 버전을 지원해야 하는 유지 관리되지 않은 레거시 분기도 있습니다.

일반적으로 표준 라이브러리는 상당히 오래된 버전의 패키지를 사용합니다(예: 3.8.10 설치 보고서).

>>> json.__version__
'2.0.9'

가장 최근의 릴리스(이 문서 작성 시점)는 3.18.1입니다. (Github 저장소의 태그가 지정된 릴리스는 3.8.2까지 거슬러 올라갑니다. 2.0.9 릴리스는 2009년으로 거슬러 올라갑니다.)

나는 아직 어떤 것에 대한 포괄적인 문서를 찾을 수 없었습니다.simplejson버전은 Python이 릴리스한 버전에 해당합니다.

언급URL : https://stackoverflow.com/questions/7771011/how-can-i-parse-read-and-use-json-in-python

반응형