Search code examples
pythonpandasfacebook-graph-api

Parse nested json file from facebook api


This is sample JSON from Facebook API

{
   "ads": {
      "data": [
         {     
            "id": "23853497907610453",
            "name": "TEST Name",
            "adcreatives": {
               "data": [
                  {
                     "id": "23853497931820453",
                     "asset_feed_spec": {
                        "videos": [
                           {
                              "video_id": "",
                              "thumbnail_url": ""
                           }
                        ],
                        "bodies": [
                           {
                              "text": ""
                           },
                           {
                              "text": ""
                           }
                        ],
                        "call_to_action_types": [
                           "SIGN_UP",
                           "LEARN_MORE"
                        ],
                        "descriptions": [
                           {
                              "text": ""
                           }
                        ],
                        "link_urls": [
                           {
                              "website_url": "URL TEST"
                           }
                        ],
                        "ad_formats": [
                           "AUTOMATIC_FORMAT"
                        ],
                        "optimization_type": "REGULAR",
                        "additional_data": {
                           "multi_share_end_card": false
                        }
                     }
                  }
               ]
            }
         },

All i need is to have dataframe which contains only 4 values from all levels:

ads.id ads.name adcreatives.id asset_feed_spec.website_url
23853497907610453 TEST Name 23853497931820453 URL TEST

I try to use:

df = pd.json_normalize(data['ads'], record_path=['data'])

But it flattened only first level:

enter image description here

Then i tried to add second path:

df = pd.json_normalize(data['ads'], record_path=['data', 'adcreatives'])

But it gives me this error

TypeError: {'id': '23853733672170453', 'name': 'utm_campaign=kz_crm_crm0123vid_auto_auto&utm_content=bizplan_1vid', 'adcreatives': {'data': [{'id': '23853733714150453', 'asset_feed_spec': {'bodies': [{'text': 'Больше никаких «зависших» сделок, забытых клиентов и просроченных дел 😎 — ведите продажи в CRM с любого устройства, с компьютера и со смартфона.\n⠀\nБесплатная CRM Битрикс24 поможет менеджерам правильно расставить приоритеты❗, подскажет, с чем нужно работать в первую очередь, и вовремя напомнит о запланированных делах, звонках, документах.\n⠀\nВся история общения с клиентами, все каналы связи, статусы по сделкам и полная аналитика по продажам всегда под рукой, в едином окне.\n⠀\nРегистрируйтесь на сайте, скачивайте приложение и управляйте продажами на новом уровне! 🔥'}, {'text': '⚡ Бесплатная CRM для малого и крупного бизнеса теперь еще удобнее ⚡— полноценная мобильная версия в вашем смартфоне!\n\nCRM помогает менеджерам и руководителям эффективно работать с клиентами и сделками даже без компьютера — в любом месте, в любое время.\n⠀\nЖмите "Подробнее", регистрируйтесь, скачивайте приложение и организуйте продажи на современном уровне!'}], 'optimization_type': 'DEGREES_OF_FREEDOM'}}]}} has non list value {'data': [{'id': '23853733714150453', 'asset_feed_spec': {'bodies': [{'text': 'Больше никаких «зависших» сделок, забытых клиентов и просроченных дел 😎 — ведите продажи в CRM с любого устройства, с компьютера и со смартфона.\n⠀\nБесплатная CRM Битрикс24 поможет менеджерам правильно расставить приоритеты❗, подскажет, с чем нужно работать в первую очередь, и вовремя напомнит о запланированных делах, звонках, документах.\n⠀\nВся история общения с клиентами, все каналы связи, статусы по сделкам и полная аналитика по продажам всегда под рукой, в едином окне.\n⠀\nРегистрируйтесь на сайте, скачивайте приложение и управляйте продажами на новом уровне! 🔥'}, {'text': '⚡ Бесплатная CRM для малого и крупного бизнеса теперь еще удобнее ⚡— полноценная мобильная версия в вашем смартфоне!\n\nCRM помогает менеджерам и руководителям эффективно работать с клиентами и сделками даже без компьютера — в любом месте, в любое время.\n⠀\nЖмите "Подробнее", регистрируйтесь, скачивайте приложение и организуйте продажи на современном уровне!'}], 'optimization_type': 'DEGREES_OF_FREEDOM'}}]} for path adcreatives. Must be list or null.

I've read a lot of posts, tried a few other tricks, but I still can't seem to get data from a deeper level. What am I doing wrong?


Solution

  • So for now i find this solution, that get only specific values from all levels, and where they are not, replaces with "nan"

    url = requests.get('API CALL')
    data = url.json()
    
    ad_id = []
    ad_name = []
    creative_id = []
    url = []
    data2 = data['ads']['data']
    for ads in data2:
        try:
            ad_id.append(ads['id'])
            ad_name.append(ads['name'])
            creative_id.append(ads['adcreatives']['data'][0]['id'])
            url.append(ads['adcreatives']['data'][0]['asset_feed_spec']['link_urls'][0]['website_url'])
        except KeyError:
            url.append('nan')
    
    df = pd.DataFrame()
    
    df['ad_id'] = ad_id
    df['ad_name'] = ad_name
    df['creative_id'] = creative_id
    df['url'] = url
    
    df
    
    

    This give me nice dataframe, that i need. Maybe there is some better solution, using pd.json_normalize

    enter image description here