首页 文章

无法使用Python循环遍历页面API响应

提问于
浏览
1

所以,我正在摸着这个 . 使用HubSpot的API,我需要获取客户端“门户”(帐户)中所有公司的列表 . 遗憾的是,标准API调用一次只能返回100家公司 . 当它确实返回响应时,它包括两个参数,这些参数使得可以通过响应进行分页 .

其中一个是 "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内容附加到列表中,所以最终我有这个包含所有120个页面的JSON响应的列表,这样我就可以解析该列表以用于不同的函数 .

我迫切需要一个解决方案:(

This is the function I am replacing in my main script:

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 回答

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

    严格来说, break 之后的 else 不是必需的,但它与Zen of Python "Explicit is better than implicit"保持一致

    请注意,您只检查一次200响应代码,如果您的循环内部出现问题,您将错过它 . 您应该将所有调用放在循环中,并且每次都要检查是否有正确的响应 .

相关问题