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

在Pandas DataFrame中迭代Google Analytics API报错及结果转DataFrame问题

问题分析与解决方案

一、解决TypeError: Object of type 'date' is not JSON serializable错误

这个报错的核心原因有两点:

  1. 日期类型不兼容:你的date_和date_date字段是Python原生的date对象,但Google Analytics API要求日期参数必须是**YYYY-MM-DD格式的字符串**,JSON无法直接序列化date对象。
  2. 参数格式错误:你给start_date和end_date传了列表(比如[f.loc[i]['date_']]),但API的dateRanges配置里,startDate和endDate只接受单个字符串,不需要用列表包裹。

修复步骤

  • 把date对象通过strftime('%Y-%m-%d')转换成符合要求的字符串;
  • 去掉参数的列表包裹,直接传入字符串。

修改后的API调用参数部分:

start_date=f.loc[i]['date_'].strftime('%Y-%m-%d'),
end_date=f.loc[i]['date_date'].strftime('%Y-%m-%d'),

同时,你的get_report函数里的dateRanges配置要对应调整(现在传的是单个字符串,无需额外处理):

"dateRanges":[{"startDate": start_date, "endDate": end_date}],

二、将API响应结构化为DataFrame

你的现有代码在结果收集上存在两个问题:

  • lista在循环内每次都会重新初始化,最后只会保留最后一次的API结果;
  • 如果print_response只是打印响应而不返回DataFrame,那df会是None,根本无法添加到列表中。

完整优化后的代码示例

假设你的print_response还没有实现响应转DataFrame的逻辑,我会帮你补充这个核心转换函数:

import pandas as pd
import time

# 定义响应转DataFrame的函数
def response_to_df(response):
    reports = response.get('reports', [])
    if not reports:
        return pd.DataFrame()
    
    report = reports[0]
    # 提取维度和指标的表头
    dim_headers = [col['name'] for col in report.get('columnHeader', {}).get('dimensions', [])]
    metric_headers = [col['name'] for col in report.get('columnHeader', {}).get('metricHeader', {}).get('metricHeaderEntries', [])]
    all_headers = dim_headers + metric_headers
    
    # 提取每行数据
    rows = []
    for row in report.get('data', {}).get('rows', []):
        dim_values = row.get('dimensions', [])
        metric_values = row.get('metrics', [])[0].get('values', [])
        rows.append(dim_values + metric_values)
    
    return pd.DataFrame(rows, columns=all_headers)

# 初始化结果列表(放在循环外面!)
result_list = []

for i in f.index:
    # 调用修复后的API请求
    api_response = get_report(
        config.service,
        start_date=f.loc[i]['date_'].strftime('%Y-%m-%d'),
        end_date=f.loc[i]['date_date'].strftime('%Y-%m-%d'),
        view_id='xxxxxxxx',
        metrics=[{'expression': 'ga:pageViews'}],
        dimensionFilterClauses= [{
            "filters": [{
                "dimensionName": "ga:pageTitle",
                "expressions": [f.loc[i]['title_']]
            }]
        }],
        dimensions=[{"name": "ga:pageTitle"}]
    )
    
    # 转换为DataFrame并添加到列表
    current_df = response_to_df(api_response)
    # 额外关联原数据的日期字段,让结果更完整
    current_df['original_start_date'] = f.loc[i]['date_']
    current_df['original_end_date'] = f.loc[i]['date_date']
    result_list.append(current_df)
    
    time.sleep(2)

# 合并所有小DataFrame为最终的大DataFrame
final_result_df = pd.concat(result_list, ignore_index=True)
print(final_result_df)

额外说明

  • 如果你的print_response原本就有返回DataFrame的逻辑,直接替换成你的函数即可;
  • 添加original_start_date和original_end_date字段,能让最终结果和原输入数据关联起来,方便后续分析;
  • 循环中的time.sleep(2)是合理的,能避免触发Google Analytics API的请求频率限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:29:36