You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

pandas json_normalize处理Facebook Graph API嵌套JSON为DataFrame问题

问题根因

直接对接口返回的完整JSON根对象调用json_normalize时,方法只会展开根节点下的一级字段,嵌套在data数组中的广告活动、insights.data下的指标数据、actions/action_values这类键值对结构的列表都不会被自动拆解,因此最终只会得到1行包含未展开嵌套结构的结果。

实现方案

分步拆解多层嵌套结构,先打平固定层级的字段,再转换行为类键值对列表为宽表,同时兼容接口分页逻辑,完整代码如下:

import requests
import pandas as pd
from pandas import json_normalize

# 替换为你的有效访问凭证
my_access_token = "YOUR_ACCESS_TOKEN"
api_url = 'https://graph.facebook.com/v14.0/act_1135563643203528/campaigns?fields=name,date_preset=last_7d,insights{actions,action_values,conversions,conversion_values,impressions}&access_token=' + my_access_token

def get_campaign_report(start_url):
    all_page_data = []
    current_url = start_url
    
    while current_url:
        resp = requests.get(current_url).json()
        campaign_list = resp.get("data", [])
        if not campaign_list:
            break
        
        # 第一层展开:把广告活动基础信息和insights下的基础指标打平
        df_base = json_normalize(
            campaign_list,
            record_path=["insights", "data"],
            meta=["name", "id"],
            sep="_"
        )

        # 工具函数:把actions/action_values这类列表转成action_type为列名的宽表
        def expand_kv_action_col(target_df, col_name, col_prefix=""):
            expanded_rows = []
            for row_idx, row in target_df.iterrows():
                action_items = row.get(col_name, [])
                if not action_items:
                    expanded_rows.append(pd.DataFrame(index=[row_idx]))
                    continue
                row_data = {f"{col_prefix}{item['action_type']}": item["value"] for item in action_items}
                expanded_rows.append(pd.DataFrame(row_data, index=[row_idx]))
            return pd.concat(expanded_rows)
        
        # 分别展开行为次数、行为价值列,价值列加前缀避免列名冲突
        df_actions = expand_kv_action_col(df_base, "actions")
        df_action_values = expand_kv_action_col(df_base, "action_values", col_prefix="conv_value_")

        # 合并所有字段,删除原始未展开的列表列
        df_page = pd.concat(
            [
                df_base.drop(columns=["actions", "action_values"], errors="ignore"),
                df_actions,
                df_action_values
            ],
            axis=1
        )
        all_page_data.append(df_page)

        # 读取下一页地址,无下一页时终止循环
        current_url = resp.get("paging", {}).get("next")
    
    # 合并所有分页数据,统一转换数值字段类型
    if not all_page_data:
        return pd.DataFrame()
    final_df = pd.concat(all_page_data, ignore_index=True)
    numeric_cols = [col for col in final_df.columns if col not in ["name", "id", "date_start", "date_stop"]]
    final_df[numeric_cols] = final_df[numeric_cols].apply(pd.to_numeric, errors="coerce")
    return final_df

# 执行拉取
df = get_campaign_report(api_url)
输出说明
  • 最终结果每行对应1个广告活动在所选时间周期的汇总数据
  • 所有行为类型(post_reaction、omni_purchase、link_click等)会自动展开为独立列,无对应行为的广告活动该列值为空
  • 转化价值类字段统一加conv_value_前缀,和行为次数字段明确区分
  • 自动遍历分页拉取全量数据,所有数值类字段自动转为数值类型,可直接用于后续计算分析

内容的提问来源于stack exchange,提问作者ibimon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:18:27