1

Espérons que quelqu'un puisse m'aider. Je tente d'extraire des données via l'API Google AdWords à l'aide de Python. Je dois extraire des données pour plusieurs comptes stockés sous un même CM.Erreur de rapport parallèle AdWords API (tuyau brisé multitraitement)

Google a un exemple de code pour ce faire en téléchargement parallèle (https://github.com/googleads/googleads-python-lib/blob/master/examples/adwords/v201607/reporting/parallel_report_download.py).

Cependant, les erreurs de code exemple avec l'erreur suivante:

Traceback (most recent call last): 
File   "C:/Users/casper.nygaard/Documents/WebTv/youtube/YouTube_ParallelDataRetrieval.py", line 226, in <module> 
main(adwords_client, REPORT_DOWNLOAD_DIRECTORY) 
File "C:/Users/casper.nygaard/Documents/WebTv/youtube/YouTube_ParallelDataRetrieval.py", line 85, in main 
process.start() 
File "C:\Users\casper.nygaard\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\process.py", line 105, in start 
self._popen = self._Popen(self) 
File "C:\Users\casper.nygaard\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\context.py", line 212, in _Popen 
return _default_context.get_context().Process._Popen(process_obj) 
File "C:\Users\casper.nygaard\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\context.py", line 313, in _Popen 
return Popen(process_obj) 
File "C:\Users\casper.nygaard\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\popen_spawn_win32.py", line 66, in __init__ 
reduction.dump(process_obj, to_child) 
File "C:\Users\casper.nygaard\AppData\Local\Programs\Python\Python35-32\lib\multiprocessing\reduction.py", line 59, in dump 
ForkingPickler(file, protocol).dump(obj) 
BrokenPipeError: [Errno 32] Broken pipe 

Je courais python 3.5, et je pense que l'exemple de code est écrit en 2.7 (je devais ajouter entre parenthèses d'impression et changement syntaxe de la gestion des exceptions) . Mais je ne sais pas si mon erreur est liée.

Pour autant que je peux voir les erreurs de code sur ces lignes:

for process in processes: 
process.start() 

Je ne suis pas expert en programmation, et pour être honnête, je ne sais pas comment déboguer cette question, de sorte que toute aide est beaucoup apprécié.

Il n'est pas obligatoire que je cours en parallèle, donc si quelqu'un a un exemple de code pour l'API AdWords pour exécuter plusieurs comptes sans multitraitement, cela serait également une aide bienvenue.

Répondre

0

Il existe une variété d'échantillons de rapports disponibles ici: https://github.com/googleads/googleads-python-lib/tree/master/examples/adwords/v201609/reporting

Il est un peu en désordre, mais je suis en cours d'exécution de ce code, basé sur l'échantillon de download_criteria_report_with_awql.py. Entrez le numéro de compte CM à la fin et il explorera tous les comptes enfants. Il existe des fonctions distinctes pour les rapports sur les campagnes et les groupes d'annonces.

#!/usr/bin/python 

from googleads import adwords 
import datetime 

# Specify where to download the file here. 
d = datetime.date.today() - datetime.timedelta(days=1) 
file_date = int(d.strftime('%Y%m%d')) 
FILE_DIRECTORY = './' 
RESULT_FILE_NAME = ' ' + str(file_date) + '.csv' 
PAGE_SIZE = 500 
REPORT_PERIOD = 'LAST_7_DAYS' 
# TODAY | YESTERDAY | LAST_7_DAYS | THIS_WEEK_SUN_TODAY | THIS_WEEK_MON_TODAY | LAST_WEEK | 
# LAST_14_DAYS | LAST_30_DAYS | LAST_BUSINESS_WEEK | LAST_WEEK_SUN_SAT | THIS_MONTH | 20170101,20171231 


def run_report(adwords_client, client_list): 
import csv 

print('Pulling AdWords API pull...') 
first_run = True 

for client in client_list: 
    print('Reporting for ' + str(client)) 
    report = get_adgroup_report(adwords_client, client) 
    report_array = report['report'].split('\n') 
    reader = csv.reader(report_array, delimiter=',') 

    print('Processing data to file...') 
    if first_run: 
     with open(FILE_DIRECTORY + '/' + RESULT_FILE_NAME, 'w', newline='\n', encoding='utf8') as csv_file: 
      writer = csv.writer(csv_file, quoting=csv.QUOTE_ALL) 
      writer.writerow(report['headers']) 
      first_run = False 
      csv_file.close() 
    else: 
     do_cleaning(reader, report['headers']) 

    # print('Report saved.') 
print('Done pulling from AdWords API.') 


def do_cleaning(reader, header): 
import csv 

# Fields that Google reports in micro amounts that need to be 'x/1000000' 
micro_array = ['AverageCpc', 'Cost', 'CostPerConversion', 'AverageCpc', 'TargetCpa', 'CpcBid'] 
# Fields that need to be cleaned and converted to percentages 
percent_array = ['CampaignDesktopBidModifier', 'CampaignMobileBidModifier', 'CampaignTabletBidModifier', 
       'AdGroupDesktopBidModifier', 'AdGroupMobileBidModifier', 'AdGroupTabletBidModifier', 
       'SearchExactMatchImpressionShare', 'SearchExactMatchImpressionShare', 'SearchImpressionShare', 
       'SearchRankLostImpressionShare'] 

with open(FILE_DIRECTORY + '/' + RESULT_FILE_NAME, 'a', newline='\n', encoding='utf8') as csv_file: 
    for row in reader: 
     if len(row) > 1: 
      writer = csv.writer(csv_file, quoting=csv.QUOTE_ALL) 

      i = 0 
      post_row = [] 
      for field in row: 
       if field == ' --': 
        field = '' 

       if header[i] in percent_array and field != '': 
        field = field.replace('%', '').replace('<', '').replace('>', '').replace(' ', '') 
        field = float(field)/100 

       if header[i] in micro_array and field != '': 
        field = int(field)/1000000 

       if isinstance(field, float): 
        field = round(field, 2) 

       post_row.append(field) 
       i += 1 
      writer.writerow(post_row) 
    csv_file.close() 


def get_account_hierarchy(client, client_id): 
# Initialize appropriate service. 
client.SetClientCustomerId(client_id) 
managed_customer_service = client.GetService('ManagedCustomerService', version='v201607') 

# Construct selector to get all accounts. 
offset = 0 
selector = { 
     'fields': ['CustomerId', 'Name'], 
     'paging': { 
       'startIndex': str(offset), 
       'numberResults': str(PAGE_SIZE) 
     } 
} 
more_pages = True 
accounts = {} 
child_links = {} 
parent_links = {} 
root_account = None 
# Shell account numbers (accounts that only contain other accounts) 
mcc_accounts = [] 

while more_pages: 
    # Get serviced account graph. 
    page = managed_customer_service.get(selector) 
    if 'entries' in page and page['entries']: 
     # Create map from customerId to parent and child links. 
     if 'links' in page: 
      for link in page['links']: 
       if link['managerCustomerId'] not in child_links: 
        child_links[link['managerCustomerId']] = [] 
       child_links[link['managerCustomerId']].append(link) 
       if link['clientCustomerId'] not in parent_links: 
        parent_links[link['clientCustomerId']] = [] 
       parent_links[link['clientCustomerId']].append(link) 
     # Map from customerID to account. 
     for account in page['entries']: 
      if account['customerId'] not in mcc_accounts: 
       accounts[account['customerId']] = account 
    offset += PAGE_SIZE 
    selector['paging']['startIndex'] = str(offset) 
    more_pages = offset < int(page['totalNumEntries']) 

# Find the root account. 
for customer_id in accounts: 
    if customer_id not in parent_links: 
     root_account = accounts[customer_id] 

return accounts 


def get_campaign_report(client, client_id): 
client.SetClientCustomerId(client_id) 
report_downloader = client.GetReportDownloader(version='v201609') 

columns = ['Date', 'AccountDescriptiveName', 'DayOfWeek', 'CampaignName', 'CampaignId', 'Device', 'Impressions', 
      'Clicks', 'Conversions', 'AverageCpc', 'Cost', 'AveragePosition', 'CostPerConversion', 
      'BiddingStrategyType', 'BiddingStrategyId', 'BiddingStrategyName', 'CampaignDesktopBidModifier', 
      'CampaignMobileBidModifier', 'CampaignTabletBidModifier', 'SearchExactMatchImpressionShare', 
      'SearchImpressionShare', 'SearchRankLostImpressionShare', 'CampaignTrialType', 'BaseCampaignId'] 
separator = ',' 
report_query = ('SELECT ' + separator.join(columns) + ' FROM CAMPAIGN_PERFORMANCE_REPORT DURING ' + REPORT_PERIOD) 

# with open('temp.csv', 'w') as output_file: 
# report_downloader.DownloadReportWithAwql(report_query, 'CSV', output_file, skip_report_header=True, 
#            skip_column_header=False, skip_report_summary=True) 

report = report_downloader.DownloadReportAsStringWithAwql(report_query, 'CSV', skip_report_header=True, 
                  skip_column_header=True, skip_report_summary=True) 
payload = {'report': report, 
      'headers': columns 
      } 
# print('Report done.') 
return payload 


def get_adgroup_report(client, client_id): 
client.SetClientCustomerId(client_id) 
report_downloader = client.GetReportDownloader(version='v201609') 

columns = ['Date', 'AccountDescriptiveName', 'DayOfWeek', 'CampaignName', 'CampaignId', 'AdGroupName', 'AdGroupId', 
      'Device', 'Impressions', 'Clicks', 'Conversions', 'Cost', 'AverageCpc', 'CostPerConversion', 
      'AveragePosition', 'BiddingStrategyType', 'BiddingStrategyId', 'BiddingStrategyName', 'CpcBid', 
      'TargetCpa', 'AdGroupDesktopBidModifier', 'AdGroupMobileBidModifier', 'AdGroupTabletBidModifier', 
      'BaseCampaignId', 'BaseAdGroupId'] 
separator = ',' 
report_query = ('SELECT ' + separator.join(columns) + ' FROM ADGROUP_PERFORMANCE_REPORT DURING ' + REPORT_PERIOD) 

# with open('temp.csv', 'w') as output_file: 
# report_downloader.DownloadReportWithAwql(report_query, 'CSV', output_file, skip_report_header=True, 
#            skip_column_header=False, skip_report_summary=True) 

report = report_downloader.DownloadReportAsStringWithAwql(report_query, 'CSV', skip_report_header=True, 
                  skip_column_header=True, skip_report_summary=True) 

payload = {'report': report, 
      'headers': columns 
      } 
# print('Report done.') 
return payload 


if __name__ == '__main__': 
mcc_client_customer_id = 'MCC account number' 
adwords_client = adwords.AdWordsClient.LoadFromStorage('adwords_credentials.yaml') 
accounts = get_account_hierarchy(adwords_client, mcc_client_customer_id) 
run_report(adwords_client, accounts)