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:
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?
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