Python 3.x 使用python脚本生成google Admob网络报告时获取HttpError 401

Python 3.x 使用python脚本生成google Admob网络报告时获取HttpError 401,python-3.x,admob,Python 3.x,Admob,下面是我用来生成Admob网络报告的代码 from apiclient.discovery import build from oauth2client.service_account import ServiceAccountCredentials import os base_path=os.path.dirname(os.path.realpath(__file__)) scopes=['https://www.googleapis.com/auth/admob.report'] ke

下面是我用来生成Admob网络报告的代码

from apiclient.discovery import build
from oauth2client.service_account import ServiceAccountCredentials
import os


base_path=os.path.dirname(os.path.realpath(__file__))
scopes=['https://www.googleapis.com/auth/admob.report']
key_file_location = base_path+'/config/service_account.json'

credentials = ServiceAccountCredentials.from_json_keyfile_name(key_file_location, scopes)



account_id='accounts/pub-XXXXXXXXXXXXXXXX'
network_report_filter = {
  'dateRange': {
    'startDate': {'year': 2020, 'month': 1, 'day': 1},
    'endDate': {'year': 2020, 'month': 2, 'day': 10}
  },
  'dimensions': ['DATE', 'APP', 'COUNTRY'],
  'metrics': ['CLICKS', 'ESTIMATED_EARNINGS'],
  'dimensionFilters': [
    {
      'dimension': 'COUNTRY',
      'matchesAny': {'values': [{'value': 'US', 'value': 'CN'}]}
    }
  ],
  'sortConditions': [
    {'dimension':'APP', 'order': 'ASCENDING'},
    {'metric':'CLICKS', 'order': 'DESCENDING'}
  ],
  'localizationSettings': {
    'currencyCode': 'USD',
    'languageCode': 'en-US'
  }
}


# Build the service object.
admob = build('admob', 'v1', credentials=credentials)

admob._resourceDesc=network_report_filter
accounts=admob.accounts()
network_report=accounts.networkReport().generate(parent=account_id)
data=network_report.execute()
它抛出下面的错误

***HttpError:https://admob.googleapis.com/v1/accounts/pub-XXXXXXXXXXXXXXXX/networkReport:generate?alt=json 返回“请求缺少所需的身份验证凭据。需要OAuth 2访问令牌、登录cookie或其他有效身份验证凭据。请参阅。“>

我已生成启用Admob API的服务帐户凭据。
但无法找出出现身份验证错误的原因。

主要问题是,上面的代码试图使用服务帐户查询api。但是,它不受支持。可以使用OAuth2.0客户端Id查询它

生成OAth2.0客户端ID的步骤:

  • 打开项目()的凭证页面
  • 生成OAuth2.0客户端ID
  • 下载生成的json文件
  • 与下面的代码一起使用
以下几点对我很有用:

Libs:

代码示例:

import csv
import sys

from googleapiclient import discovery
from googleapiclient.http import build_http
from oauth2client import tools
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow


class AdMobAPI:

    def __init__(self):
        scope = 'https://www.googleapis.com/auth/admob.report'
        name = 'admob'
        version = 'v1'

        flow = OAuth2WebServerFlow(client_id='<todo: replace with a client_id from the secret json>',
                                   client_secret='<todo: replace with a secret from the secret json>',
                                   scope=scope)
        storage = Storage(name + '.dat')
        credentials = storage.get()
        if credentials is None or credentials.invalid:
            credentials = tools.run_flow(flow, storage)
        http = credentials.authorize(http=build_http())
        self.admob = discovery.build(name, version, http=http)

    # Convert to the list of dictionaries
    def report_to_list_of_dictionaries(self, response):
        result = []

        for report_line in response:
            if report_line.get('row'):
                print(report_line)
                row = report_line.get('row')
                dm = {}
                if row.get('dimensionValues'):
                    for key, value in row.get('dimensionValues').items():
                        if value.get('value') and value.get('displayLabel'):
                            dm.update({key: value.get('value')})
                            dm.update({key + '_NAME': value.get('displayLabel')})
                        else:
                            dm.update({key: next(filter(None, [value.get('value'), value.get('displayLabel')]))})
                if row.get('metricValues'):
                    for key, value in row.get('metricValues').items():
                        dm.update({key: next(filter(None, [value.get('value'), value.get('microsValue'), value.get('integerValue')]))})
                result.append(dm)
        return result

    def generate_report(self, publisher_id):
        date_range = {'startDate': {'year': 2020, 'month': 4, 'day': 1},
                      'endDate': {'year': 2020, 'month': 4, 'day': 1}}
        dimensions = ['DATE', 'APP', 'PLATFORM', 'COUNTRY']
        metrics = ['ESTIMATED_EARNINGS', 'IMPRESSIONS', 'CLICKS',
                   'AD_REQUESTS', 'MATCHED_REQUESTS']
        sort_conditions = {'dimension': 'DATE', 'order': 'DESCENDING'}
        report_spec = {'dateRange': date_range,
                       'dimensions': dimensions,
                       'metrics': metrics,
                       'sortConditions': [sort_conditions]}

        request = {'reportSpec': report_spec}
        return self.admob.accounts().networkReport().generate(
                parent='accounts/{}'.format(publisher_id),
                body=request).execute()

api = AdMobAPI()
raw_report = api.generate_report('<todo: replace with publisher id, smth like pub-[0-9]+>')
report_as_list_of_dictionaries = api.report_to_list_of_dictionaries(raw_report)

# Convert to CSV
dict_writer = csv.DictWriter(sys.stdout, report_as_list_of_dictionaries[0].keys())
dict_writer.writeheader()
dict_writer.writerows(report_as_list_of_dictionaries)
导入csv
导入系统
从GoogleAppClient导入发现
从googleapiclient.http导入构建\u http
从oauth2client导入工具
从oauth2client.file导入存储
从oauth2client.client导入OAuth2WebServerFlow
AdMobAPI类:
定义初始化(自):
范围=https://www.googleapis.com/auth/admob.report'
名称='admob'
版本='v1'
flow=OAuth2WebServerFlow(客户端id='',
客户_机密=“”,
范围=范围)
存储=存储(名称+'.dat')
凭据=存储。获取()
如果凭据为无或凭据无效:
凭据=工具。运行\u流(流、存储)
http=credentials.authorize(http=build\u http())
self.admob=discovery.build(名称、版本、http=http)
#转换为字典列表
def报告到词典列表(自我,响应):
结果=[]
对于响应的报告行:
如果报告_line.get('row'):
打印(报告行)
行=报告行。获取('行')
dm={}
如果row.get('dimensionValues'):
对于键,行.get('dimensionValues')中的值。items():
如果value.get('value')和value.get('displayLabel'):
dm.update({key:value.get('value')})
dm.update({key+''u NAME':value.get('displayLabel')})
其他:
update({key:next(过滤器(无,[value.get('value'),value.get('displayLabel')))))
如果row.get('metricValues'):
对于键,行.get('metricValues')中的值。项()
update({key:next(过滤器(无、[value.get('value')、value.get('microsValue')、value.get('integerValue')))))
结果追加(dm)
返回结果
def生成报告(自身、发布者id):
日期范围={'startDate':{'year':2020,'month':4,'day':1},
'endDate':{'year':2020,'month':4,'day':1}
维度=['日期','应用','平台','国家']
指标=['估计收入','印象','点击',
'广告请求','匹配的广告请求']
排序条件={'dimension':'DATE','order':'DESCENDING'}
报告规格={'dateRange':日期范围,
“维度”:维度,
“指标”:指标,
“排序条件”:[sort_条件]}
请求={'reportSpec':报告\u spec}
返回self.admob.accounts().networkReport().generate(
parent='accounts/{}'。格式(publisher\u id),
body=request.execute()
api=AdMobAPI()
原始报告=api.generate报告(“”)
报告为字典列表=api。报告为字典列表(原始报告)
#转换为CSV
dict_writer=csv.DictWriter(sys.stdout,报告为词典[0].keys()的列表)
口述作者、书面负责人()
dict_writer.writerows(报告为词典列表)

github上提供了工作示例:
import csv
import sys

from googleapiclient import discovery
from googleapiclient.http import build_http
from oauth2client import tools
from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow


class AdMobAPI:

    def __init__(self):
        scope = 'https://www.googleapis.com/auth/admob.report'
        name = 'admob'
        version = 'v1'

        flow = OAuth2WebServerFlow(client_id='<todo: replace with a client_id from the secret json>',
                                   client_secret='<todo: replace with a secret from the secret json>',
                                   scope=scope)
        storage = Storage(name + '.dat')
        credentials = storage.get()
        if credentials is None or credentials.invalid:
            credentials = tools.run_flow(flow, storage)
        http = credentials.authorize(http=build_http())
        self.admob = discovery.build(name, version, http=http)

    # Convert to the list of dictionaries
    def report_to_list_of_dictionaries(self, response):
        result = []

        for report_line in response:
            if report_line.get('row'):
                print(report_line)
                row = report_line.get('row')
                dm = {}
                if row.get('dimensionValues'):
                    for key, value in row.get('dimensionValues').items():
                        if value.get('value') and value.get('displayLabel'):
                            dm.update({key: value.get('value')})
                            dm.update({key + '_NAME': value.get('displayLabel')})
                        else:
                            dm.update({key: next(filter(None, [value.get('value'), value.get('displayLabel')]))})
                if row.get('metricValues'):
                    for key, value in row.get('metricValues').items():
                        dm.update({key: next(filter(None, [value.get('value'), value.get('microsValue'), value.get('integerValue')]))})
                result.append(dm)
        return result

    def generate_report(self, publisher_id):
        date_range = {'startDate': {'year': 2020, 'month': 4, 'day': 1},
                      'endDate': {'year': 2020, 'month': 4, 'day': 1}}
        dimensions = ['DATE', 'APP', 'PLATFORM', 'COUNTRY']
        metrics = ['ESTIMATED_EARNINGS', 'IMPRESSIONS', 'CLICKS',
                   'AD_REQUESTS', 'MATCHED_REQUESTS']
        sort_conditions = {'dimension': 'DATE', 'order': 'DESCENDING'}
        report_spec = {'dateRange': date_range,
                       'dimensions': dimensions,
                       'metrics': metrics,
                       'sortConditions': [sort_conditions]}

        request = {'reportSpec': report_spec}
        return self.admob.accounts().networkReport().generate(
                parent='accounts/{}'.format(publisher_id),
                body=request).execute()

api = AdMobAPI()
raw_report = api.generate_report('<todo: replace with publisher id, smth like pub-[0-9]+>')
report_as_list_of_dictionaries = api.report_to_list_of_dictionaries(raw_report)

# Convert to CSV
dict_writer = csv.DictWriter(sys.stdout, report_as_list_of_dictionaries[0].keys())
dict_writer.writeheader()
dict_writer.writerows(report_as_list_of_dictionaries)