提问人:Arun.K 提问时间:5/3/2023 最后编辑:Michael RuthArun.K 更新时间:5/5/2023 访问量:75
无法从 URL 获取多个 Json 响应
Unable to get multiple Json responses from URL
问:
我将一个 id 值传递给 API url 以获取 JSON 响应,但只得到一个响应,其余的都抛出了 500 个错误。我收集列表中的 id,并在 while 循环中将 id 作为参数传递给 API URL,以提取数据。
###Get id in a variable##
df_filter=spark.sql("""select distinct ID from filter_view""")
rdd = df_filter.rdd
listOfRows = rdd.collect()
counter = 0
##total_results = []
while counter < len(listOfRows):
url += '?ids=' + listOfRows[counter].ID
response = requests.get(url,headers=headers)
if response.status_code == 200:
json_response = response.json()
##total_results.append(json_response)
df2 = pd.json_normalize(json_response, record_path=['entities'])
display(df2)
else:
print("Error: HTTP status code " + str(response.status_code))
counter +=1
我只得到一个 ID 的输出,其余的都以 500 个错误结束。
期望输出:
ID---ItemID--Details
1 100 text
1 101 text
2 200 text
2 300 text
3 400 sometext
3 500 sometext
我得到的输出:
ID---ItemID--Details
1 100 text
1 101 text
Error: HTTP status code 500
Error: HTTP status code 500
Error: HTTP status code 500
Error: HTTP status code 500
Error: HTTP status code 500
Error: HTTP status code 500
答:
第一次迭代会生成一个有效的 URL:,但由于它是使用串联和赋值构建的,因此第二次迭代会在需要时生成 。baseURL/?ids=1
baseURL/?ids=1?ids=2
baseURL/?ids=2
while counter < len(listOfRows):
response = requests.get(f'{url}?ids={listOfRows[counter].ID}', headers=headers)
API 是否支持在单个请求中获取多个资源?通常,对于复数查询参数(如 ),它将采用逗号分隔的资源 ID 列表 () 或数组 (, 或 )。如果是这样,那么提出这样的请求会更有效率,对 API 提供者来说也更礼貌。ids
?ids=1,2,3
?ids[]=1&ids[]=2&ids[]=3
?ids=1&ids=2&ids=3
response = requests.get(
url + '?ids=' + ','.join([row.ID for row in listOfRows]),
headers=headers
)
您可能需要更改代码来分析新响应。
如果不支持多个 GET,请至少将其转换为 for 循环。无需跟踪和测试,它将提高可读性。counter
counter < len(listOfRows)
df_filter=spark.sql("""select distinct ID from filter_view""")
rdd = df_filter.rdd
listOfRows = rdd.collect()
for row in listOfRows:
response = requests.get(f'{url}?ids={row.ID}', headers=headers)
if response.status_code == 200:
json_response = response.json()
df2 = pd.json_normalize(json_response, record_path=['entities'])
display(df2)
else:
print("Error: HTTP status code " + str(response.status_code))
更新:基于评论
我有 5000 多个 ID 需要一一传递。这怎么能在 20 个块中通过?
生成表单的 URL,每个 URL 不超过 20 个 ID。...?ids=1&ids=2&ids=3...
from itertools import islice
def chunker(it: seq, chunksize):
iterator = iter(it)
while chunk := list(islice(iterator, chunksize)):
yield chunk
for id_chunk in chunker([row.ID for row in listOfRows], 20):
response = requests.get(
f'{url}?ids=' + '&ids='.join(id_chunk),
headers=headers
)
将可迭代对象拆分为长度为 <= 的 s。首先筛选仅 ID。然后将 ID 分块为长度为 20 的 s。生成 URL 并发出请求。
感谢kafran的chunker()。
chunker()
list
chunksize
listOfRows
list
评论
listOfRows
评论
'?ids=...'
response = requests.get(url + '?ids=' + listOfRows[counter].ID, headers=headers)
url