为多个mcc帐户提取Adwords报告

问题描述 投票:0回答:1

我正在寻找一种方法,使用AdWords API for python一次性为多个mcc_account提取报告,通过以下代码,我可以使用google_ads.YAML文件一次传递一个MCC帐户。

有没有办法从CSV或文本文件中传递多个MCC帐户并为其提取报告?

YAML文件

# AdWordsClient configurations
adwords:
    #############################################################################
    # Required Fields                                                           #
    #############################################################################
    developer_token: XXXXXX
    #############################################################################
    # Optional Fields                                                           #
    #############################################################################
    client_customer_id: XXXX
    user_agent: XXXX
    # partial_failure: True
    # validate_only: True
    #############################################################################
    # OAuth2 Configuration                                                      #
    # Below you may provide credentials for either the installed application or #
    # service account flows. Remove or comment the lines for the flow you're    #
    # not using.                                                                #
    #############################################################################
    # The following values configure the client for the installed application
    # flow.
    client_id: XXXXX
    client_secret: XXXX
    refresh_token: XXXXX

import multiprocessing
import os
from Queue import Empty
import time

import googleads.adwords
import googleads.errors

# Timeout between retries in seconds.
BACKOFF_FACTOR = 5
# Maximum number of processes to spawn.
MAX_PROCESSES = multiprocessing.cpu_count()
# Maximum number of retries for 500 errors.
MAX_RETRIES = 5
# Maximum number of items to be sent in a single API response.
PAGE_SIZE = 100
# Directory to download the reports to.
REPORT_DOWNLOAD_DIRECTORY = '.'


def _DownloadReport(process_id, report_download_directory, customer_id,
                    report_definition):
    report_downloader = (googleads.adwords.AdWordsClient.LoadFromStorage('                                                                      'googleads.yaml')
                            .GetReportDownloader())

    filepath = os.path.join(report_download_directory,
                            'adgroup_%d.csv' % customer_id)
    retry_count = 0

    while True:
        print ('[%d/%d] Loading report for customer ID "%s" into "%s"...'
                % (process_id, retry_count, customer_id, filepath))
        try:
            with open(filepath, 'wb') as handler:
                report_downloader.DownloadReport(
                    report_definition, output=handler,
                    client_customer_id=customer_id)
            return True, {'customerId': customer_id}
        except googleads.errors.AdWordsReportError as e:
            if e.code == 500 and retry_count < MAX_RETRIES:
                time.sleep(retry_count * BACKOFF_FACTOR)
            else:
                print ('Report failed for customer ID "%s" with code "%d" after "%d" '
                        'retries.' % (customer_id, e.code, retry_count + 1))
                return (False, {'customerId': customer_id, 'code': e.code,
                                'message': e.message})


class ReportWorker(multiprocessing.Process):
    """A worker Process used to download reports for a set of customer IDs."""

    def __init__(self, report_download_directory, report_definition,
                    input_queue, success_queue, failure_queue):
        """Initializes a ReportWorker.

        Args:
            report_download_directory: A string indicating the directory where you
            would like to download the reports.
            report_definition: A dict containing the report definition that you would
            like to run against all customer IDs in the input_queue.
            input_queue: A Queue instance containing all of the customer IDs that
            the report_definition will be run against.
            success_queue: A Queue instance that the details of successful report
            downloads will be saved to.
            failure_queue: A Queue instance that the details of failed report
            downloads will be saved to.
        """
        super(ReportWorker, self).__init__()
        self.report_download_directory = report_download_directory
        self.report_definition = report_definition
        self.input_queue = input_queue
        self.success_queue = success_queue
        self.failure_queue = failure_queue

    def run(self):
        while True:
            try:
                customer_id = self.input_queue.get(timeout=0.01)
            except Empty:
                break
            result = _DownloadReport(self.ident, self.report_download_directory,
                                        customer_id, self.report_definition)
            (self.success_queue if result[0] else self.failure_queue).put(result[1])


def GetCustomerIDs(client):
    """Retrieves all CustomerIds in the account hierarchy.

    Note that your configuration file must specify a client_customer_id belonging
    to an AdWords manager account.

    Args:
        client: an AdWordsClient instance.
    Raises:
        Exception: if no CustomerIds could be found.
    Returns:
        A Queue instance containing all CustomerIds in the account hierarchy.
    """
    # For this example, we will use ManagedCustomerService to get all IDs in
    # hierarchy that do not belong to MCC accounts.
    managed_customer_service = client.GetService('ManagedCustomerService',
                                                    version='v201809')

    offset = 0

    # Get the account hierarchy for this account.
    selector = {
        'fields': ['CustomerId'],
        'predicates': [{
            'field': 'CanManageClients',
            'operator': 'EQUALS',
            'values': [False]
        }],
        'paging': {
            'startIndex': str(offset),
            'numberResults': str(PAGE_SIZE)
        }
    }

    # Using Queue to balance load between processes.
    queue = multiprocessing.Queue()
    more_pages = True

    while more_pages:
        page = managed_customer_service.get(selector)

        if page and 'entries' in page and page['entries']:
            for entry in page['entries']:
                queue.put(entry['customerId'])
        else:
            raise Exception('Can\'t retrieve any customer ID.')
        offset += PAGE_SIZE
        selector['paging']['startIndex'] = str(offset)
        more_pages = offset < int(page['totalNumEntries'])

    return queue


def main(client, report_download_directory):
    # Determine list of customer IDs to retrieve report for.
    input_queue = GetCustomerIDs(client)
    reports_succeeded = multiprocessing.Queue()
    reports_failed = multiprocessing.Queue()

    # Create report definition.
    report_definition = {
        'reportName': 'Custom ADGROUP_PERFORMANCE_REPORT',
        'dateRangeType': 'LAST_7_DAYS',
        'reportType': 'ADGROUP_PERFORMANCE_REPORT',
        'downloadFormat': 'CSV',
        'selector': {
            'fields': ['CampaignId', 'AdGroupId', 'Impressions', 'Clicks',
                        'Cost'],
            # Predicates are optional.
            'predicates': {
                'field': 'AdGroupStatus',
                'operator': 'IN',
                'values': ['ENABLED', 'PAUSED']
            }
        },
    }

    queue_size = input_queue.qsize()
    num_processes = min(queue_size, MAX_PROCESSES)
    print 'Retrieving %d reports with %d processes:' % (queue_size, num_processes)

    # Start all the processes.
    processes = [ReportWorker(report_download_directory,
                                report_definition, input_queue, reports_succeeded,
                                reports_failed)
                    for _ in range(num_processes)]

    for process in processes:
        process.start()

    for process in processes:
        process.join()

    print 'Finished downloading reports with the following results:'
    while True:
        try:
            success = reports_succeeded.get(timeout=0.01)
        except Empty:
            break
        print '\tReport for CustomerId "%d" succeeded.' % success['customerId']

    while True:
        try:
            failure = reports_failed.get(timeout=0.01)
        except Empty:
            break
        print ('\tReport for CustomerId "%d" failed with error code "%s" and '
                'message: %s.' % (failure['customerId'], failure['code'],
                                    failure['message']))


if __name__ == '__main__':
    adwords_client = googleads.adwords.AdWordsClient.LoadFromStorage(
        'googleads.yaml')
    main(adwords_client, REPORT_DOWNLOAD_DIRECTORY)

如何获取多个MCC帐户的效果报告?

python google-adwords google-ads-api
1个回答
1
投票

您需要创建不同的googleads.adwords.AdWordsClient实例以实现相同,因为一个客户端只能使用一个adwords帐户(mcc或单个帐户)。

要创建AdWordsClient实例,您可以自动化流程而无需使用YAML文件进行配置,并使用下面的代码创建相同的代码(其余代码将保持不变) -

"""Initializes a AdManagerClient without using yaml-cached credentials.
While our LoadFromStorage method provides a useful shortcut to instantiate a
client if you regularly use just one set of credentials, production applications
may need to swap out users. This example shows you how to create an OAuth2
client and a AdManagerClient without relying on a yaml file.
"""


from googleads import ad_manager
from googleads import oauth2

# OAuth2 credential information. In a real application, you'd probably be
# pulling these values from a credential storage.
CLIENT_ID = 'INSERT_CLIENT_ID_HERE'
CLIENT_SECRET = 'INSERT_CLIENT_SECRET_HERE'
REFRESH_TOKEN = 'INSERT_REFRESH_TOKEN_HERE'

# Ad Manager API information.
APPLICATION_NAME = 'INSERT_APPLICATION_NAME_HERE'

# Client customer id
CLIENT_CUSTOMER_ID = 'INSERT_CLIENT_CUSTOMER_ID_HERE'

def main(client_id, client_secret, refresh_token, application_name):
  oauth2_client = oauth2.GoogleRefreshTokenClient(
      client_id, client_secret, refresh_token)

  ad_manager_client = ad_manager.AdManagerClient(
      oauth2_client, application_name,client_customer_id=CLIENT_CUSTOMER_ID)

  networks = ad_manager_client.GetService('NetworkService').getAllNetworks()
  for network in networks:
    print ('Network with network code "%s" and display name "%s" was found.'
           % (network['networkCode'], network['displayName']))


if __name__ == '__main__':
  main(CLIENT_ID, CLIENT_SECRET, REFRESH_TOKEN, APPLICATION_NAME)

Code reference