programing

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

muds 2023. 3. 22. 22:14
반응형

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

웹 API에서 데이터를 얻기 위해 코드를 작성했습니다.API에서 JSON 데이터를 해석할 수 있었습니다만, 결과는 매우 복잡해 보입니다.예를 들어 다음과 같습니다.

>>> my_json
{'name': 'ns1:timeSeriesResponseType', 'declaredType': 'org.cuahsi.waterml.TimeSeriesResponseType', 'scope': 'javax.xml.bind.JAXBElement$GlobalScope', 'value': {'queryInfo': {'creationTime': 1349724919000, 'queryURL': 'http://waterservices.usgs.gov/nwis/iv/', 'criteria': {'locationParam': '[ALL:103232434]', 'variableParam': '[00060, 00065]'}, 'note': [{'value': '[ALL:103232434]', 'title': 'filter:sites'}, {'value': '[mode=LATEST, modifiedSince=null]', 'title': 'filter:timeRange'}, {'value': 'sdas01', 'title': 'server'}]}}, 'nil': False, 'globalScope': True, 'typeSubstituted': False}

이 데이터를 보면 원하는 특정 데이터를 볼 수 있습니다.1349724919000라벨이 붙은 값'creationTime'.

이 값을 직접 얻을 수 있는 코드를 작성하려면 어떻게 해야 합니까?

이 값을 찾기 위해 검색 논리가 필요하지 않습니다.응답을 보면 필요한 것을 알 수 있습니다.특정 코드로 변환하여 특정 값을 하드 코드 방식으로 추출하는 방법만 알면 됩니다.몇 가지 튜토리얼을 읽었기 때문에 이 튜토리얼을 사용할 필요가 있다는 것을 알고 있습니다.[]네스트된 목록과 사전의 요소에 액세스합니다.그러나 복잡한 케이스의 경우 어떻게 동작하는지는 정확하게 알 수 없습니다.

좀 더 일반적으로, 데이터에 대한 "경로"가 무엇인지 파악하고 데이터에 대한 코드를 작성하려면 어떻게 해야 합니까?

참고로, 원래의 JSON이 어떻게 생겼는지, 포맷이 예쁜 것을 확인해 봅시다.

>>> print(json.dumps(my_json, indent=4))
{
    "name": "ns1:timeSeriesResponseType",
    "declaredType": "org.cuahsi.waterml.TimeSeriesResponseType",
    "scope": "javax.xml.bind.JAXBElement$GlobalScope",
    "value": {
        "queryInfo": {
            "creationTime": 1349724919000,
            "queryURL": "http://waterservices.usgs.gov/nwis/iv/",
            "criteria": {
                "locationParam": "[ALL:103232434]",
                "variableParam": "[00060, 00065]"
            },
            "note": [
                {
                    "value": "[ALL:103232434]",
                    "title": "filter:sites"
                },
                {
                    "value": "[mode=LATEST, modifiedSince=null]",
                    "title": "filter:timeRange"
                },
                {
                    "value": "sdas01",
                    "title": "server"
                }
            ]
        }
    },
    "nil": false,
    "globalScope": true,
    "typeSubstituted": false
}

이를 통해 데이터의 구조를 보다 명확하게 확인할 수 있습니다.

구체적인 경우, 먼저 아래의 대응하는 값을 확인합니다.'value'키를 누릅니다.그것은 또 다른 명령이다; 우리는 그것의 가치에 접근할 수 있다.'queryInfo'같은 방법으로, 그리고 마찬가지로,'creationTime'거기서부터요.

원하는 값을 얻기 위해 이러한 액세스를 하나씩 넣기만 하면 됩니다.

my_json['value']['queryInfo']['creationTime'] # 1349724919000

어떻게 그걸 특정 코드로 변환해서 특정 값을 추출하는지만 알면 돼요. 하드코드 방식으로요

API에 다시 접속하면 새로운 데이터가 코드 예상과 일치하지 않을 수 있습니다.에러 처리를 추가하는 것이 도움이 될 수 있습니다.예를 들어,.get()인덱싱이 아닌 데이터 사전 액세스:

name = my_json.get('name') # will return None if 'name' doesn't exist

다른 방법은 키를 명시적으로 테스트하는 것입니다.

if 'name' in resp_dict:
    name = resp_dict['name']
else:
    pass

그러나 추가 액세스가 필요한 경우 이러한 접근 방식이 실패할 수 있습니다.플레이스 홀더 결과None사전이나 리스트가 아니기 때문에, 그 방법으로 액세스 하려고 하면, 다시 실패합니다(와 함께).TypeError'심플한 것이 복잡한 것보다 낫다' '허락보다 용서를 구하는 것이 쉽다'는 점에서 간단한 해결책은 예외 처리를 사용하는 것입니다.

try:
    creation_time = my_json['value']['queryInfo']['creationTime']
except (TypeError, KeyError):
    print("could not read the creation time!")
    # or substitute a placeholder, or raise a new exception, etc.

다음으로 단순한 JSON 데이터에서 단일 값을 로드하여 앞뒤로 JSON으로 변환하는 예를 나타냅니다.

import json

# load the data into an element
data={"test1": "1", "test2": "2", "test3": "3"}

# dumps the json object into an element
json_str = json.dumps(data)

# load the json to a string
resp = json.loads(json_str)

# print the resp
print(resp)

# extract an element in the response
print(resp['test1'])

이거 먹어봐.

여기서는 COVID API(JSON 배열)에서 상태 코드만 가져옵니다.

import requests

r = requests.get('https://api.covid19india.org/data.json')

x = r.json()['statewise']

for i in x:
  print(i['statecode'])

이것을 시험해 보세요.

from functools import reduce
import re


def deep_get_imps(data, key: str):
    split_keys = re.split("[\\[\\]]", key)
    out_data = data
    for split_key in split_keys:
        if split_key == "":
            return out_data
        elif isinstance(out_data, dict):
            out_data = out_data.get(split_key)
        elif isinstance(out_data, list):
            try:
                sub = int(split_key)
            except ValueError:
                return None
            else:
                length = len(out_data)
                out_data = out_data[sub] if -length <= sub < length else None
        else:
            return None
    return out_data


def deep_get(dictionary, keys):
    return reduce(deep_get_imps, keys.split("."), dictionary)

그 후 다음과 같이 사용할 수 있습니다.

res = {
    "status": 200,
    "info": {
        "name": "Test",
        "date": "2021-06-12"
    },
    "result": [{
        "name": "test1",
        "value": 2.5
    }, {
        "name": "test2",
        "value": 1.9
    },{
        "name": "test1",
        "value": 3.1
    }]
}

>>> deep_get(res, "info")
{'name': 'Test', 'date': '2021-06-12'}
>>> deep_get(res, "info.date")
'2021-06-12'
>>> deep_get(res, "result")
[{'name': 'test1', 'value': 2.5}, {'name': 'test2', 'value': 1.9}, {'name': 'test1', 'value': 3.1}]
>>> deep_get(res, "result[2]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[-1]")
{'name': 'test1', 'value': 3.1}
>>> deep_get(res, "result[2].name")
'test1'

언급URL : https://stackoverflow.com/questions/12788217/how-can-i-extract-a-single-value-from-a-nested-data-structure-such-as-from-pars

반응형