使用循环上一次迭代的结果更新循环的输入

Update the input of a loop with a result from the previous iteration of the loop

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

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

当查询 API 时,你传递了一个看起来像这样的字典:

{'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参数the documentation on 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')

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

到目前为止一切顺利。这是我尝试的循环:

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() 时,查询的值与上面的第一个代码块相同(变量 sessions1_qr,带有所有 API 调用参数的字典)。在每次循环迭代中,这应该更新,以便 pageToken 的值被响应的 nextPageToken 值替换。

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

根据评论讨论添加一些屏幕截图:

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

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 所以你的循环将停止。