1

Надеюсь, кто-то может мне помочь. Я пытаюсь извлечь данные через API Google AdWords с помощью Python. Мне нужно вытащить данные для нескольких учетных записей, хранящихся в одном MCC.Ошибка параллельного отчета API Adwords (многопроцессорная ломаная труба)

У Google есть пример кода для этого в качестве параллельной загрузки (https://github.com/googleads/googleads-python-lib/blob/master/examples/adwords/v201607/reporting/parallel_report_download.py).

Однако ошибки Пример кода со следующей ошибкой:

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 

Я бегу питона 3.5, и я думаю, что пример кода написано в 2.7 (я должен был добавить печать скобки и синтаксис обработки исключений изменения) , Но я не знаю, связана ли моя ошибка.

Насколько я могу видеть ошибки кода на этих линиях:

for process in processes: 
process.start() 

Я не эксперт программирования, и честно говоря, я понятия не имею, как отладить этот конкретный вопрос, так что любая помощь гораздо оценили.

Это не требование, чтобы я работал параллельно, поэтому, если у кого-либо есть пример кода для API AdWords для работы с несколькими учетными записями без многопроцессорной обработки, то это также приветствуется.

ответ

0

Есть множество образцов отчетов, доступных здесь: https://github.com/googleads/googleads-python-lib/tree/master/examples/adwords/v201609/reporting

Это немного сумбурно, но я бегу этот код, на основе выборки download_criteria_report_with_awql.py. Введите номер учетной записи Центра клиентов в конце и просканируйте все дочерние учетные записи. Существуют отдельные функции для отчетов по кампаниям и группам объявлений.

#!/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) 

 Смежные вопросы

  • Нет связанных вопросов^_^