首页 > 解决方案 > 使用循环上一次迭代的结果更新循环的输入

问题描述

(我添加了 google-analytics api 标签,但我怀疑我的问题更多是我的循环方法中的一个根本缺陷,详情如下)

我正在使用 Python 来查询 Google Analytics API (V4)。已经使用我的凭据成功连接到 API,我正在尝试遍历 API 返回的每个 10k 结果集以获取完整的结果集。

查询 API 时,您传递的 dict 看起来像这样:

{'reportRequests':[{'viewId': '1234567', # my actual view id goes here of course
    'pageToken': 'go', # can be any string initially (I think?)
    'pageSize': 10000,
    'samplingLevel': 'LARGE',
    'dateRanges': [{'startDate': '2018-06-01', 'endDate': '2018-07-13'}],
    'dimensions': [{'name': 'ga:date'}, {'name': 'ga:dimension1'}, {'name': 'ga:dimension2'}, {'name': 'ga:userType'}, {'name': 'ga:landingpagePath'}, {'name': 'ga:deviceCategory'}],
    'metrics': [{'expression': 'ga:sessions'}, {'expression': 'ga:bounces'}, {'expression': 'ga:goal1Completions'}]}]}

根据pageToken 参数上的 Google Analytics API V4 文档:

"A continuation token to get the next page of the results. Adding this to the request will return the rows after the pageToken. The pageToken should be the value returned in the nextPageToken parameter in the response to the reports.batchGet request. "

我的理解是我需要以 10,000 个块(允许的最大查询结果大小)查询 API,为此我必须将每个查询结果中返回的 nextPageToken 字段的值传递给新查询。

在研究中,听起来当所有结果都返回时,nextPageToken 字段将是一个空字符串。

所以,我尝试了一个while循环。为了进入循环阶段,我构建了一些函数:

## generates the dimensions in the right format to use in the query
def generate_dims(dims):
    dims_ar = []
    for i in dims:
        d = {'name': i}
        dims_ar.append(d)
    return(dims_ar)

## generates the metrics in the right format to use in the query
def generate_metrics(mets):
    mets_ar = []
    for i in mets:
        m = {'expression': i}
        mets_ar.append(m)
    return(mets_ar)

## generate the query dict
def query(pToken, dimensions, metrics, start, end):
    api_query = {
            'reportRequests': [
                    {'viewId': VIEW_ID,
                     'pageToken': pToken,          
                     'pageSize': 10000,
                     'samplingLevel': 'LARGE',
                     'dateRanges': [{'startDate': start, 'endDate': end}],
                     'dimensions': generate_dims(dimensions),
                     'metrics': generate_metrics(metrics)
                     }]
    }
    return(api_query)

上述 3 个函数的示例输出:

sessions1_qr = query(pToken = pageToken,
                     dimensions = ['ga:date', 'ga:dimension1', 'ga:dimension2',
                                   'ga:userType', 'ga:landingpagePath',
                                   'ga:deviceCategory'],
                     metrics = ['ga:sessions', 'ga:bounces', 'ga:goal1Completions'],
                     start = '2018-06-01',
                     end = '2018-07-13')

这个结果看起来像这篇文章中的第一个代码块。

到目前为止,一切都很好。这是我尝试的循环:

def main(query):
    global pageToken, store_response

    # debugging, was hoping to see print output on each iteration (I didn't)
    print(pageToken)

    while pageToken != "":
        analytics = initialize_analyticsreporting()
        response = get_report(analytics, query)
        pageToken = response['reports'][0]['nextPageToken'] # < IT ALL COMES DOWN TO THIS LINE HERE
        store_response['pageToken'] = response

    return(False) # don't actually need the function to return anything, just append to global store_response.

然后我尝试运行它:

pageToken = "go" # can be any string to get started
store_response = {}
sessions1 = main(sessions1_qr)

会发生以下情况:

所以,看起来我的循环只运行一次。

盯着代码我怀疑它与我传递给的查询参数的值有关main()。当我最初调用main()查询的值与上面的第一个代码块相同(变量 session1_qr,包含所有 API 调用参数的字典)。在每次循环迭代中,这应该更新,以便将 pageToken 的值替换为响应的 nextPageToken 值。

换句话说,简而言之,我需要使用循环的上一次迭代的结果来更新循环的输入。我的逻辑显然有缺陷,因此非常感谢任何帮助。

每个评论讨论添加一些屏幕截图: 在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

标签: pythongoogle-analytics-apigoogle-analytics-firebase

解决方案


这是我解决这个问题的方法:

def main(query):
    global pageToken, store_response

    while pageToken != "":
        # debugging, was hoping to see print output on each iteration (I didn't)
        print(pageToken)
        analytics = initialize_analyticsreporting()
        response = get_report(analytics, query)

        # note that this has changed -- you were using 'pageToken' as a key
        # which would overwrite each response
        store_response[pageToken] = response

        pageToken = response['reports'][0]['nextPageToken'] # update the pageToken
        query['reportRequests'][0]['pageToken'] = pageToken # update the query


    return(False) # don't actually need the function to return anything, just append to global store_response.

即手动更新查询数据结构,并将每个响应存储pageToken为字典键。

大概最后一页有''nextPageToken所以你的循环将停止。


推荐阅读