Как получить узел из сложного вложенного JSON ответа в Python - PullRequest
0 голосов
/ 03 апреля 2020

Привет, у меня есть вложенный ответ JSON, необходимо получить указанный c узел (очевидно, вложенную структуру). В приведенном ниже примере предположим, что это «тело», если оно не содержит никаких внутренних узлов, возвращает тот же элемент, ie. 'body', если в 'body' есть узел 'Message', он должен вернуть узел 'Message'. Как я могу обработать этот сценарий в Python.

{
  "messageId": "56ba2b85-fb61-4a28-97d3-941237228582",
  "receiptHandle": "AQEB9mKPGdkuDgQkH3tNZ5pMd",
  "body": {
    "Type": "Notification",
    "MessageId": "467a4ce6-4a1e-5cab-8801-1be6b30a621f",
    "TopicArn": "arn:aws:sns:us-east-2:ttttt:TEST",
    "Subject": "01  Publish for TEST ",
    "Message": "{\\\"Store\\\":\\\"I01\\\",\\\"Loc\\\":\\\"I03\\\",\\\"User\\\":\\\"P37\\\",\\\"Mile\\\":\\\"1500\\\",\\\"Status\\\":true}\"",
    "Timestamp": "2020-04-03T08:41:56.047Z",
    "SignatureVersion": "1",
    "Signature": "Kg",
    "SigningCertURL": "something.com",
    "UnsubscribeURL": "subscribermoke.com"
  },
  "attributes": {
    "ApproximateReceiveCount": "42",
    "SentTimestamp": "1585903316106",
    "SenderId": "AIDAJQR6QDGQ7PATMSYEY",
    "ApproximateFirstReceiveTimestamp": "1585903316106"
  },
  "messageAttributes": {},
  "eventSource": "aws:sqs",
  "eventSourceARN": "arn:aws:sqs:us-east-:jjjjjj:sample-Dev",
  "awsRegion": "us-east"
}

Дополнительная информация: Вот небольшое изменение в теле JSON, пожалуйста, найдите его для справки.

"Сообщение": "{\" Store \ ": \" I01 \ ", \" Loc \ ": \" I03 \ ", \" Пользователь \ ": \" P37 \ ", \" Mile \ ": \" 1500 \ ", \" Status \ ": true}"
Я хочу содержимое внутри "Message" как dict

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Вам нужна некоторая форма рекурсии ... но сначала вам нужно исправить свой объект данных (я думаю).

Вот схема того, что вам нужно:

from pprint import pprint
import json

MESSAGE = {
  "messageId": "56ba2b85-fb61-4a28-97d3-941237228582",
  "receiptHandle": "AQEB9mKPGdkuDgQkH3tNZ5pMd",
  "body": {
    "Type": "Notification",
    "MessageId": "467a4ce6-4a1e-5cab-8801-1be6b30a621f",
    "TopicArn": "arn:aws:sns:us-east-2:ttttt:TEST",
    "Subject": "01  Publish for TEST ",
    "Message": "{\\\"Store\\\":\\\"I01\\\",\\\"Loc\\\":\\\"I03\\\",\\\"User\\\":\\\"P37\\\",\\\"Mile\\\":\\\"1500\\\",\\\"Status\\\":true}\"",
    "Timestamp": "2020-04-03T08:41:56.047Z",
    "SignatureVersion": "1",
    "Signature": "Kg",
    "SigningCertURL": "something.com",
    "UnsubscribeURL": "subscribermoke.com"
  },
  "attributes": {
    "ApproximateReceiveCount": "42",
    "SentTimestamp": "1585903316106",
    "SenderId": "AIDAJQR6QDGQ7PATMSYEY",
    "ApproximateFirstReceiveTimestamp": "1585903316106"
  },
  "messageAttributes": {},
  "eventSource": "aws:sqs",
  "eventSourceARN": "arn:aws:sqs:us-east-:jjjjjj:sample-Dev",
  "awsRegion": "us-east"
}

def find_messages_in_body(body):
    if "Message" in body:
        submsg = body["Message"]
        print(submsg)
        print(type(submsg))
        submsg = json.loads(submsg)
        submsg = find_messages_in_body(submsg)
        return(submsg)
    else:
        return body

pprint(find_messages_in_body(MESSAGE["body"]))

Но когда вы запустите это, вы обнаружите, что это бомбы, потому что значение submsg является строкой, но не допустимая строка JSON.

Итак ... что, опять же, ваш желаемый результат? Вы уверены, что правильно скопировали введенные данные? Есть ли у вас другие примеры входных данных?

Также ... возможно ли, что будет несколько возможных "дополнительных сообщений"? Если это так, вам нужно будет вернуть этот список или преобразовать его в генератор (с yield вместо return операторов). НО ПЕРВЫЙ ... проверьте ваш объект данных: MESSAGE["body"]["Message"] в настоящее время недействителен JSON.

0 голосов
/ 03 апреля 2020

Прежде всего давайте преобразуем ваш ответ в словарь:

res_dict = json.loads(reaponse)

Чтобы извлечь нужное поле:

body = res_dict.get("body")
res = body.get("Message")  if body else body
# bare in mind that if Message doesnt exist in body, the result will be None. If you want to return body in that case, replace 
# body.get("Message") with body.get("Message", body)
...