Как вы анализируете данные json, которые находятся под несколькими слоями?

#python #parsing #postman #jsonparser

Вопрос:

Цель кода-взять информацию json,которую я получаю,и проанализировать ее в необработанных данных о местоположении( адрес, почтовый адрес и т. Д.). Я довольно новичок в кодировании, и это одноразовая задача, с которой я столкнулся в школьном проекте, поскольку я изучаю географию и мне нужны местоположения всех McDonald’ов в Канаде.Поэтому любые другие инструменты обучения приветствуются. Однако главная проблема, с которой я сталкиваюсь, заключается в том, что я хочу написать

 for blank in blanks['']:
 

таким образом, я могу получить данные для вывода в формате csv. Однако я заметил, что мои данные находятся под несколькими слоями.
Например:

 {
    "features": [
        {
            "geometry": {
                "coordinates": [
                    -79.28662,
                    43.68758
                ]
            },
            "properties": {
                "name": "Vic Park/Gerrard",
                "shortDescription": "VIC PARK/G",
                "longDescription": "VIC PARK/GERRARD",
                "todayHours": "06:00 - 22:00",
                "driveTodayHours": "00:00 - 00:00",
                "id": "195500517230-en-ca",
                "filterType": [
                    "ALL_DAY_BREAKFAST",
                    "BAKERY",
                    "BREAKFAST",
                    "CYT",
                    "DRIVETHRU",
                    "INDOORDINING",
                    "MCCAFE",
                    "MOBILEOFFERS",
                    "MOBILEORDERS",
                    "PARKINGAREA",
                    "TWENTYFOURHOURS",
                    "WIFI"
                ],
                "addressLine1": "2480 GERRARD STREET EAST",
                "addressLine2": "",
                "addressLine3": "SCARBOROUGH",
                "addressLine4": "Canada",
                "subDivision": "",
                "postcode": "M1N 4C3",
                "customAddress": "SCARBOROUGH, M1N 4C3",
                "telephone": "4166903659",
 

Информация, которую я хочу, находится в разделе «Свойства» в соответствии с тем, как она выглядит для меня (не уверен), но моя

 for store in stores['features']:
 

заявление. Не позволяет мне захватывать информацию об адресной строке 1 или другую информацию отдельно для csv. Мне интересно, есть ли у кого-нибудь решение для анализа таких данных, как это.

P. S Я включил весь свой код на случай, если возникнет более глубокая проблема.

 import requests
import csv
import json

url = "https://www.mcdonalds.com/googleapps/GoogleRestaurantLocAction.do?method=searchLocationamp;latitude=43.6936965amp;longitude=-79.2969938amp;radius=1000000amp;maxResults=1700amp;country=caamp;language=en-caamp;showClosed=amp;hours24Text=Open 24 hr"

payload={}
files={}
headers = {
  'authority': 'www.mcdonalds.com',
  'sec-ch-ua': '" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91"',
  'accept': '*/*',
  'x-requested-with': 'XMLHttpRequest',
  'sec-ch-ua-mobile': '?0',
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36',
  'sec-fetch-site': 'same-origin',
  'sec-fetch-mode': 'cors',
  'sec-fetch-dest': 'empty',
  'referer': 'https://www.mcdonalds.com/ca/en-ca/restaurant-locator.html',
  'accept-language': 'en-GB,en-US;q=0.9,en;q=0.8',
  'cookie': 'bm_sz=C04645E7F7A956C5F9D9C5A20DEAEC97~YAAQ1Cv2SEtfMBN6AQAAItxfEwwTVV2V2Tr7UWpPt1Ps7gl84FzQlmbWIm4kBBh5dxlK3w8RenwiEiKtvERE6dLmrwPwJUuy 14gU/LeEZvP uxzyBr04oQXdcSEQuiOgdkAGasqnBrTw1mp5E5iehnRpvHBDdSqh8wRSgJV0eG4f8YwSz66BfntCBALtQNCAFK2; _abck=F05779F2345218EA4989FF467D897C5A~0~YAAQ1Cv2SExfMBN6AQAAItxfEwaIwCrBeP25JBhBb7TX HmnLQgrj1TkosrB oHSv9ctrxRukqEDUaHPL1KkjpqjY1XY1yyulQ0ZRhsEfhY968YVsTOqfiosAu3kykd3pJG/bQ37XHwWs5qXpIdhMXRwJwXmkYtl3ETG8kXK2iZ22Q31COaSjNVACLaa7s9tCk9ItgLvUj5x9Nldjnd8AdXR0pXicrQY1IaruJyNqwMcJv42AUHW7iH4Ex9ZOSYsgEjLMNd44mS525X/gSNUTSOzoqoWsnH4MU59vfgLTwc2hVncAv67LBViTLxbWw4eVAvz7Z5phQfCmvoIy0PD8gy5iwPDMaD3GASrK9xScDPAPUI2wquxmSJ f2cQaxZQKhvJCeH9cz14OZfx8ksA2ss53E0l0kDvgmnw~-1~-1~-1; ak_bmsc=BA4817D8DEE20E92C1E6251C54FC124348F62BD48F5F00005F91C9608B679D5F~plUkbYfsvYr5dCayJ9dMGEJ3QDgkmkv2mLpE7pCY9vW0xrdawvmyxfSnupw/4F7C48Akdn8PKsBniqz 7F RZb8v4AkvH3c0RuvnynqJoni kJcDYtPOxdMvdtGdTlZGIkSQNfpcxHNQDVlzojdSBX0vyBh/8seKQv10U67M7m787olYzg9jnsUwk3/VHBrnMDogiWJT8rNV7saSXunN0pAgucZWo/XhCpTJL tI9urt0=; MCDCountry_code=US; bm_mi=BEE06312635FD442995BC0237BAFDA7C~f/RxgMW/JJSUc/wB9ZRg9fPD/76 wq/TaoWEZR1/ttrAiVTO256xhDTsVYc/kdHIjWkxvfO4XDcBjqe4hQ4qXt8Anpfi09vna/zcC7l6OVWpWeRSoZNztl7h5VF407L3XG 9CpzjSHNcaqAPRk5d0J5gLMtL/KmR8XBkAC0Syim7ST97nxNrPfLdlkSPMGm4Oy86xvY5PH5Nu47zS/gwhanBFg69tAdrQdaZewE2eGuzoJPsZit3UsihTzhXc4LY92hfSdh3/kZRId NE8Jp0w==; bm_sv=7CACE3495320A7C0A6CF8F41DFE0EB36~F9KzvznVNk/fE4 ijLD5H/szY7O161rWlemmShElumIW7HN49Gq2d9Sd2tqBjCa9sJOX4zoehAkc8WvsID5Idon/hDlDeLJZuqnEmff4PN4a9yst3R170rBCm1egzGvCBmB1jq9aCwQm5VgIJgloPOdpiIPfD3kDxFbKhqMuS5U=; JSESSIONID=64PZkBXhhpvNjM4NganzSZ0r1npIIaM7Fo84EsxN.eap7node7; _abck=F05779F2345218EA4989FF467D897C5A~-1~YAAQ1Cv2SExyMBN6AQAA5Et0EwZueCejZbKz1VDGCq2sB43Yx4dq0SiiGeUS6gVpXRIdw3rA3OdpNGHq7tVzQ IvPpEKwLML9736x1qB5SQxV3jai89y2B2QF6K8nKtyrDAes0qbeTyIrHu0Rh1HLs7CjNxiLi0wswbCZfSsPI6fJZiEt Itre3lfmua/HkhIRwpVTKqlVN5eQ8XIX s1jJbINx/jUmMTW jB5k4A5NARGChYH7rJQGYIT/oyZYpSbS3Yweqa4FRgGMW4gYZBN39 t2xSfewADLdpihfOnoZtakw9VhcvAKaf4mEzjB7WEfNJIZSjSE8DzvbJNIF41MGuAhhrnEBwBE8uVCZsA 2qjVPSADVp2Nn8JanJXCbucnLFOLsmPz3oVtGzentht1cHog4 eYOUlmw~0~-1~-1; bm_sv=7CACE3495320A7C0A6CF8F41DFE0EB36~F9KzvznVNk/fE4 ijLD5H/szY7O161rWlemmShElumIW7HN49Gq2d9Sd2tqBjCa9sJOX4zoehAkc8WvsID5Idon/hDlDeLJZuqnEmff4PN5ZCTzA250oKEeVeXaa6j4gEGJ9RRtrTXQdYXzzSx6fM9aLwif We2vtIc1yLQgTt4=',
  'dnt': '1'
} 

response = requests.request("GET", url, headers = headers, data = payload, files = files)


stores = json.loads(response.text)

with open('Mcdonlocation.csv', mode='w') as CSVFile:
    writer = csv.writer(CSVFile, delimiter=",", quotechar='"', quoting=csv.QUOTE_MINIMAL)

    writer.writerow([
        "addressLine1",
        "addressLine2",
        "addressLine3",
        "subDivision",
        "postcode",
        "telephone"
        ])

    for store in stores['features']:
        row = []
        Match_Address1= store['properties']["addressLine1"]
        Match_Address2= store['properties']["addressLine2"]
        Match_Address3= store['properties']["addressLine3"]
        subDivision= store['properties']["subDivision"]
        Postalcode= store['properties']["postcode"]
        telephone= store['properties']["telephone"]

        row.append(Match_Address1)
        row.append(Match_Address2)
        row.append(Match_Address3)
        row.append(subDivision)
        row.append(Postalcode)
        row.append(telephone)
        writer.writerow(row)
 

Комментарии:

1. магазин[«Адресная строка 1»] -> магазин[«свойства»][«Адресная строка 1»] и так далее

2. @юрий спасибо, что сработало! , Однако это не позволяет мне получить номер телефона. Есть какие-нибудь идеи о том, почему это так ?

3. Ошибка, которую я получаю сейчас::: телефон = магазин[‘свойства’][«телефон»] Ключевая ошибка: ‘телефон’

4. Я не знаю, Джон. stores['features'] это список словарей. В первом словаре, который вы показываете, определенно есть «телефон». Может быть, 2-й или более поздний не делает этого?

5. @John_Muir возможно, в нем отсутствует запись о телефоне. Проверьте, существует ли он с помощью «если»телефон» в магазине [«свойства»]:»

Ответ №1:

Я думаю, что основной ответ на ваши вопросы звучит так: «посмотрите на тип». Таблица преобразования Python json сообщает вам, чего ожидать для каждого типа. Давайте загрузим ваш файл и посмотрим, что у нас есть, в соответствии с интерпретатором Python:

 >>> input = dat.read()
>>> stores = json.loads(input)
>>> type(stores)
<class 'dict'>
>>> type(stores['features'])
<class 'list'>
>>> type( stores['features'][0] )
<class 'dict'>
>>> type( stores['features'][0]['properties'] )
<class 'dict'>
>>> type( stores['features'][0]['properties']['telephone'] )
<class 'str'>
>>> stores['features'][0]['properties']['telephone']
'4166903659'
 

У каждого объекта есть тип; у каждого типа есть методы. Просто двигайтесь дальше по списку.

Комментарии:

1. Поэтому я обновил инструкцию, и все, кроме телефонов, перемещается в excel. Я получаю ошибку телефон = хранить [«свойства»] [«телефон»] Ошибка ключа: «телефон». Получаю ли я эту ошибку, потому что только что использовал правильный метод ввода? Кроме того, вы можете просмотреть изменение в исходном сообщении сейчас, если это поможет ответить на мой вопрос.

Ответ №2:

Похоже, что ваши данные структурированы следующим образом:

 features:
- geometry:
    coordinates:
    - float
    - float
  properties:
    addressLine1: str
    addressLine2: str
    addressLine3: str
    addressLine4: str
    customAddress: str
    driveTodayHours: str
    filterType:
    - str
    - ...
    id: str
    longDescription: str
    name: str
    postcode: str
    shortDescription: str
    subDivision: str
    telephone: str
    todayHours: str
 

Вы хотите извлечь информацию из отдельных элементов «функций», которые, по-видимому, являются хранилищами, поэтому вы начинаете с кода, подобного вашей существующей логике:

 for store in data['features']:
   csv_row = process_store(store)
 

Оттуда вам просто нужно решить, что вы хотите извлечь из информации, например:

 coord_1 = store['coordinates'][0]
custom_address = store['properties']['customAddress']
...
 

. По сравнению с вашим существующим кодом, я думаю, вы просто не заметили, что есть properties атрибут для доступа за пределами начального features уровня.

Комментарии:

1. Итак, теперь я получаю все, кроме номера телефона, я получаю код ошибки телефон = магазин [«свойства»] [«телефон»] Ключевая ошибка: «телефон. Я обновил свой первоначальный пост, чтобы показать внесенные мной изменения. Ошибка, которую я получаю, потому что я просто не нашел правильный путь к ней или какая-то другая проблема?

2. По крайней мере, в предоставленных вами данных телефон иногда присутствует, но, возможно, он присутствует не всегда . Попробуйте .get('telephone') вместо ['telephone']