2016-03-22 3 views
1

Schleife. Also kratze ich meinen Kopf mit diesem. Mit der HubSpot-API muss ich eine Liste aller Firmen im "Portal" meines Kunden erhalten. Leider gibt der Standard-API-Aufruf nur 100 Unternehmen gleichzeitig zurück. Wenn es eine Antwort zurückgibt, enthält es zwei Parameter, die Paging durch Antworten möglich machen.Kann nicht durch paged API-Antworten mit Python

Einer davon ist "has-more": True (dies lässt Sie wissen, wenn Sie weitere Seiten erwarten können) und die andere ist "offset":12345678 (der Zeitstempel durch die Anforderung zu kompensieren.)

Diese beiden Parameter sind Dinge, die Sie wieder passieren kann in den nächsten API-Aufruf, um die nächste Seite zu erhalten. So könnte zum Beispiel die anfängliche API-Aufruf wie folgt aussehen:

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

Während die Anrufe verfolgen könnte wie folgt aussehen:

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

So ist es das, was ich versucht habe, so weit:

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

Das Problem ist, dass es immer die gleichen 100 Ergebnisse zurückgibt; Dies passiert, weil der Parameter "has-more":True beim ersten Aufruf wahr ist, also wird er immer die gleichen zurückgeben ...

Mein ideales Szenario ist, dass ich in der Lage bin, alle Unternehmen über ungefähr 120 Antwortseiten zu analysieren (Es gibt rund 12000 Unternehmen). Während ich jede Seite passiere, möchte ich ihren JSON-Inhalt an eine Liste anhängen, so dass ich schließlich diese Liste mit den JSON-Antworten aller 120 Seiten habe, so dass ich diese Liste für die Verwendung in einer anderen Funktion parsen kann .

ich in einer verzweifelten Notwendigkeit einer Lösung bin :(

Dies ist die Funktion, die ich in meinem Haupt-Skript bin ersetzt:

  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)) 

Antwort

1

Das Problem, das scheint zu sein:

  • Sie erhalten den Offset in Ihrem ersten Anruf, aber tun Sie nichts mit den tatsächlichen Unternehmensdaten, die dieser Aufruf zurückgibt
  • Sie verwenden dann denselben Offset in Ihrer while-Schleife. Sie verwenden das neue nie aus nachfolgenden Aufrufen. Deshalb bekommen Sie jedes Mal die gleichen Firmen.

Ich denke, dieser Code für get_companies() sollte für Sie arbeiten. Ich kann es nicht testen, natürlich, aber hoffentlich ist es OK:

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)) 

Streng, die else nach den break ist nicht erforderlich, aber es ist mit dem Zen of Python im Einklang „Explicit ist besser als implizites“

Beachten Sie, dass Sie nur einmal nach einem Antwortcode von 200 suchen. Wenn etwas in Ihrer Schleife schief geht, werden Sie es vermissen. Sie sollten wahrscheinlich alle Ihre Anrufe in die Schleife setzen und jedes Mal nach einer korrekten Antwort suchen.

+0

Hallo @SiHa, danke für die Antwort - leider, dass auch das gleiche Ergebnis zurückgegeben, obwohl die ersten 100 sofort statt eins nach dem anderen zurück (was eine Verbesserung ist!Es tut uns Leid) – Marko

+0

@Marko, hatte ich die Tatsache übersehen, dass man verschiedene Namen wurden mit ('create_get_recent_companies ...' 'vs get_more_companies_call') innerhalb und außerhalb Ihres while-Schleife. Dies bedeutete, dass in meinem ersten Entwurf, obwohl mehr Ergebnisse in der Schleife abgerufen wurden, die * erste * Antwort jedes Mal durchlaufen wurde. Ich habe die Namen jetzt geändert, damit sie gleich sind. Hoffentlich wird es jetzt funktionieren. – SiHa

+0

@SiHia du bist eine absolute Legende - das hat total funktioniert. Ich habe noch eine Frage. Das obige Skript ist ein "Testskript" - ich habe versucht, die Funktionalität vom Hauptskript abzugrenzen. Zurück im Hauptskript jedoch war die Funktion, die ich ersetzen musste, die, die ich jetzt oben hinzugefügt habe ... Was denkst du, ist der beste Weg, um die Ergebnisse jeder Seite der Ergebnisse zu sammeln? Ich wollte versuchen, es an eine Liste anzuhängen, oder meinst du, ich könnte es einfach "zurückgeben", wie es ursprünglich oben gemacht wurde? – Marko