2016-03-22 1 views
1

Итак, я почесываю голову этим. Используя API HubSpot, мне нужно получить список ВСЕХ компаний на «портале» моего клиента (учетной записи). К сожалению, стандартный вызов API возвращает только 100 компаний за раз. Когда он возвращает ответ, он включает в себя два параметра, которые делают возможным пейджинг через ответы.Невозможно выполнить циклический отклик API с Python

Одним из них является "has-more": True (это позволяет вам знать, если вы можете ожидать каких-либо дополнительных страниц), а другой "offset":12345678 (метка времени, чтобы компенсировать просьбу.)

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

"https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}".format(hapikey=wta_hubspot_api_key) 

В то время как последующие вызовы могут выглядеть следующим образом:

"https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}&offset={offset}".format(hapikey=wta_hubspot_api_key, offset=offset) 

Так это то, что я пытался до сих пор:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import sys 
import os.path 
import requests 
import json 
import csv 
import glob2 
import shutil 
import time 
import time as howLong 
from time import sleep 
from time import gmtime, strftime 

HubSpot_Customer_Portal_ID = "XXXXXX" 

wta_hubspot_api_key = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" 

findCSV = glob2.glob('*contact*.csv') 

theDate = time=strftime("%Y-%m-%d", gmtime()) 
theTime = time=strftime("%H:%M:%S", gmtime()) 

try: 
    testData = findCSV[0] 
except IndexError: 
    print ("\nSyncronisation attempted on {date} at {time}: There are no \"contact\" CSVs, please upload one and try again.\n").format(date=theDate, time=theTime) 
    print("====================================================================================================================\n") 
    sys.exit() 

for theCSV in findCSV: 

    def get_companies(): 
     create_get_recent_companies_call = "https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}".format(hapikey=wta_hubspot_api_key) 
     headers = {'content-type': 'application/json'} 
     create_get_recent_companies_response = requests.get(create_get_recent_companies_call, headers=headers) 
     if create_get_recent_companies_response.status_code == 200: 

      offset = create_get_recent_companies_response.json()[u'offset'] 
      hasMore = create_get_recent_companies_response.json()[u'has-more'] 

      while hasMore == True: 
       for i in create_get_recent_companies_response.json()[u'companies']: 
        get_more_companies_call = "https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}&offset={offset}".format(hapikey=wta_hubspot_api_key, offset=offset) 
        get_more_companies_call_response = requests.get(get_more_companies_call, headers=headers) 
        companyName = i[u'properties'][u'name'][u'value'] 
        print("{companyName}".format(companyName=companyName)) 


     else: 
      print("Something went wrong, check the supplied field values.\n") 
      print(json.dumps(create_get_recent_companies_response.json(), sort_keys=True, indent=4)) 

    if __name__ == "__main__": 
     get_companies() 
     sys.exit() 

Проблема в том, что она просто возвращает те же самые интуитивные 100 результатов; это происходит потому, что параметр "has-more":True истинен при первоначальном вызове, поэтому он просто будет возвращать те же самые ...

Мой идеальный сценарий заключается в том, что я могу разобрать ВСЕ компании примерно на 120 страницах ответов (около 12000 компаний). Когда я просматриваю каждую страницу, я хотел бы добавить ее в список JSON, поэтому в конечном итоге у меня есть этот список, содержащий ответы JSON на всех 120 страницах, так что я могу разобрать этот список для использования в другой функции ,

Я отчаянно нуждается в решении :(

Это функция я замена в моей основной сценарий:

  def get_companies(): 

       create_get_recent_companies_call = "https://api.hubapi.com/companies/v2/companies/recent/modified?hapikey={hapikey}".format(hapikey=wta_hubspot_api_key) 
       headers = {'content-type': 'application/json'} 
       create_get_recent_companies_response = requests.get(create_get_recent_companies_call, headers=headers) 
       if create_get_recent_companies_response.status_code == 200: 

        for i in create_get_recent_companies_response.json()[u'results']: 
         company_name = i[u'properties'][u'name'][u'value'] 
         #print(company_name) 
         if row[0].lower() == str(company_name).lower(): 
          contact_company_id = i[u'companyId'] 
          #print(contact_company_id) 
          return contact_company_id 
       else: 
        print("Something went wrong, check the supplied field values.\n") 
        #print(json.dumps(create_get_recent_companies_response.json(), sort_keys=True, indent=4)) 

ответ

1

Проблема, кажется, что:

  • Вы получаете смещение в своем первом вызове, но ничего не делаете с фактическими данными компаний, которые этот вызов возвращает.
  • Затем вы используете это же смещение в цикле while; вы никогда не будете использовать новый из последующих вызовов. Вот почему вы каждый раз получаете одни и те же компании.

Я думаю, что этот код для get_companies() должен работать на вас. Я не могу проверить это, очевидно, но, надеюсь, это нормально:

def get_companies(): 
     create_get_recent_companies_call = "https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}".format(hapikey=wta_hubspot_api_key) 
     headers = {'content-type': 'application/json'} 
     create_get_recent_companies_response = requests.get(create_get_recent_companies_call, headers=headers) 
     if create_get_recent_companies_response.status_code == 200: 

      while True: 
       for i in create_get_recent_companies_response.json()[u'companies']: 
        companyName = i[u'properties'][u'name'][u'value'] 
        print("{companyName}".format(companyName=companyName)) 
       offset = create_get_recent_companies_response.json()[u'offset'] 
       hasMore = create_get_recent_companies_response.json()[u'has-more'] 
       if not hasMore: 
        break 
       else: 
        create_get_recent_companies_call = "https://api.hubapi.com/companies/v2/companies/?hapikey={hapikey}&offset={offset}".format(hapikey=wta_hubspot_api_key, offset=offset) 
        create_get_recent_companies_response = requests.get(create_get_recent_companies_call, headers=headers) 


     else: 
      print("Something went wrong, check the supplied field values.\n") 
      print(json.dumps(create_get_recent_companies_response.json(), sort_keys=True, indent=4)) 

Строго говоря, else после break не требуется, но это в соответствии с Zen of Python «Явное лучше, чем неявное»

Обратите внимание, что вы только проверяете код ответа 200 один раз, если что-то пойдет не так внутри вашего цикла, вы пропустите его. Вы должны, вероятно, поместить все свои звонки внутри цикла и каждый раз проверять правильный ответ.

+0

Привет @SiHa, спасибо за ответ - к сожалению, это также вернуло тот же результат, хотя и сразу же вернул первые 100, а не один за другим (что является улучшением!) – Marko

+0

@Marko Извините, я пропустил тот факт, что вы использовали разные имена ('create_get_recent_companies ...' vs 'get_more_companies_call') внутри и снаружи цикла while. Это означало, что в моем первом проекте, хотя в цикле были получены больше результатов, каждый раз повторялся * первый * ответ. Теперь я изменил имена, чтобы они были одинаковыми. Надеюсь, теперь это сработает. – SiHa

+0

@SiHia вы абсолютная легенда - это полностью сработало. У меня есть еще один вопрос. Сценарий выше - «тестовый скрипт» - я пытался сузить функциональность от основного сценария. Однако в основном сценарии функция, которую мне нужно заменить, - это тот, который я добавил выше ... как вы думаете, лучший способ собрать результаты каждой страницы результатов? Я собирался попытаться добавить его в список, или вы думаете, что я могу просто «вернуть» его, как это делалось ранее? – Marko