Цикл пагинации API Google Analytics не заканчивается и не обновляет значение pageToken в новом запросе - Python - PullRequest
0 голосов
/ 01 февраля 2019

Я загружаю некоторые данные из Google Analytics, используя Google API v4.Я получаю данные и пытаюсь использовать параметр pageToken для запроса следующей страницы, когда превышен размер страницы.Тем не менее, моя функция разбивки на страницы, которая должна передавать новый pageToken в новый запрос, входит в цикл, где выполняет бесконечно один и тот же первый запрос (учитывая, что в этой строке: print(response['reports'][0]['nextPageToken']) всегда выводится максимальное значение pageize, то естьзначение nextPageToken берется с самого первого запроса).

Запрос должен выдать ~ 8000 результатов / строк.

Я пытался создать переменную для параметра pageToken в запросе и заставить эту переменную принимать значение nextPageTokenв новом запросе, сделанном рекурсивной функцией:

pageTokenVariable = "whatever"

sample_request = {
  'viewId': '1234',
  'dateRanges': {
      'startDate': datetime.strftime(datetime.now() - timedelta(days = 1),'%Y-%m-%d'),
      'endDate': datetime.strftime(datetime.now(),'%Y-%m-%d')
  },
  'dimensions': [
      {'name': 'ga:date'},
      {'name': 'ga:eventlabel'}
  ],
  'metrics': [
      {'expression': 'ga:users'},
      {'expression': 'ga:totalevents'}
  ],
  'pageToken':pageTokenVariable,
    'pageSize': 1000
}

# pagination function
def main(client, pageTokenVariable):

    response = client.reports().batchGet(
    body={
        'reportRequests':sample_request
    }).execute()

    if 'nextPageToken' in response['reports'][0]:
            print(response['reports'][0]['nextPageToken']) #trying to debug
            pageTokenVariable = response['reports'][0]['nextPageToken']
            response = main(client, pageTokenVariable)

    return(response)

Тем не менее, он не работает должным образом.Что мне не хватает?

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Вам нужно сделать что-то вроде этого

### Something like this works for me

list = [] #I usually store the output of the pagination in a list

# pagination function
def main(client, pageTokenVariable):
    return analytics.reports().batchGet(
        body={
            'reportRequests': [
            {
            'viewId': '123',
            "pageToken": pageTokenVariable,
            #All your other stuff like dates etc goes here
            }]
        }
    ).execute()

response = main(client, "0")

for report in response.get(reports, []) #All the stuff you want to do
    pagetoken = report.get('nextPageToken', None) #Get your page token fron the FIRST request and store it a variabe
    columnHeader = report.get('columnHeader', {})
    dimensionHeaders = columnHeader.get('dimensions', [])
    metricHeaders = columnHeader.get('metricHeader', {}).get('metricHeaderEntries', [])
    rows = report.get('data', {}).get('rows', [])
    for row in rows:
        # create dict for each row
        dict = {}
        dimensions = row.get('dimensions', [])
        dateRangeValues = row.get('metrics', [])

        # fill dict with dimension header (key) and dimension value (value)
        for header, dimension in zip(dimensionHeaders, dimensions):
          dict[header] = dimension

        # fill dict with metric header (key) and metric value (value)
        for i, values in enumerate(dateRangeValues):
          for metric, value in zip(metricHeaders, values.get('values')):
            #set int as int, float a float
            if ',' in value or ',' in value:
              dict[metric.get('name')] = float(value)
            else:
              dict[metric.get('name')] = int(value)
        list.append(dict) #Append that data to a list as a dictionary

    while pagetoken: #This says while there is info in the nextPageToken get the data, process it and add to the list
        response = main(client, pagetoken)
            for row in rows:
            # create dict for each row
            dict = {}
            dimensions = row.get('dimensions', [])
            dateRangeValues = row.get('metrics', [])

            # fill dict with dimension header (key) and dimension value (value)
            for header, dimension in zip(dimensionHeaders, dimensions):
            dict[header] = dimension

            # fill dict with metric header (key) and metric value (value)
            for i, values in enumerate(dateRangeValues):
            for metric, value in zip(metricHeaders, values.get('values')):
                #set int as int, float a float
                if ',' in value or ',' in value:
                dict[metric.get('name')] = float(value)
                else:
                dict[metric.get('name')] = int(value)
            list.append(dict) #Append that data to a list as a dictionary

#So to recap
#You make an initial call to your function passing a pagetoken to get it started.
#Get the nextPageToken), process the data and append to list
#If there is data in the nextPageToken call the function, process, add to list until nextPageToken is empty
0 голосов
/ 01 февраля 2019

Я не знаю, является ли это возможным ответом, но рассматривали ли вы вопрос об удалении pageSize и добавлении параметра max-results ?

Эта опция позволяет запроситьдо 10.000 элементов, и, если у вас более 10.000, вы можете использовать опцию start-index , чтобы начать с 10.000, 20.000 и т. д.

Вы всегда можете узнать, сколько результатоввсего, потому что одно поле в ответе содержит эту информацию.

...