如何解决在Python中使用next_link进行分页的正确方法是什么?
我正在尝试为每个“切片”收集250条记录。我总共有1429条记录,所以6片250条记录足以收集我的所有记录。我尝试使用下面的代码执行此操作,但是在运行它时,它只返回251至500条记录。我的预期结果是收到1至1429条记录。有人可以告诉我我做错了吗?
import requests
import json
import math
res = r.json()
token = res['access_token']
headers = {'Authorization': 'Bearer ' + token}
proxies = {'https': 'proxy.***.***.com:8080'}
mod_date = 'ModifiedOn gt 2020-01-31'
col = 'Field1,Field2,Field3,Field4'
params1 = (('$count','true'),)
response1 = requests.get('https://***-***-***.***.nl/odata/***',headers=headers,params=params1,proxies=proxies)
data = response1.json()
next_link = data['@odata.nextLink'] #<--- this is my 'next_link' link.
total_records = data['@odata.count'] #<--- this are the total records '1429'
records_per_page = next_link[313:] #<--- this are the records per page '250'
total_pages = total_records / int(records_per_page) #<--- these are the total pages '5.7'
list_to_store_all_sclices = []
list_pages = [i for i in range(1,math.ceil(total_pages) +1)] #<--- '5,7' is rounded to 6 and placed in list.
for x in list_pages:
response2 = requests.get(next_link.format(x),proxies=proxies)
data = response2.json()
list_to_store_all_sclices.append(data)
print(list_to_store_all_sclices)
解决方法
您似乎在这里犯了两个错误:
- 您创建了一个列表,其中填充了
list_to_store_all_sclices = []
但是您没有append
到该列表的第一个结果。
仅在发出第二个请求后附加数据。
- 您从第一个结果中获得了下一个链接。但是随后您尝试在其上使用
format
。当您尝试格式化没有方括号的字符串时,不会发生任何事情。自己尝试一下:
link = 'this is a string'
link2 = 'this is {}'
insert = 'some insertion'
print(link.format(insert))
print(link2.format(insert))
查看formatting synthax上的文档,以了解格式化的工作原理。
由于您没有提供next_link
的更多示例,并且服务器响应实际上是什么样的,因此我们无法为您提供确切的说明。但是我们可以假设服务器为每个响应提供了一个新的链接。因此,您需要在获得每个响应后捕获它,并在您的请求中使用它。否则,您将一遍又一遍地使用相同的链接,就像您提供的代码一样。
您的代码可能看起来像这样:
while next_link:
new_response = requests.get(next_link,headers=headers,proxies=proxies)
new_data = new_response.json()
list_to_store_all_sclices.append(new_data)
print(list_to_store_all_sclices)
next_link = new_data.get('@odata.nextLink',None)
但是您需要查看next_link
的外观,以便知道是否/如何修改它以发出正确的请求。交互式外壳程序是一个很好的工具。
编辑以回答您的问题:
- 现在我们只在谈论1429条记录,如果我有数百万个记录,那python处理的内容就不那么多了吗?
这实际上取决于记录的大小。例如,如果每个字符串都是10个字符的字符串,那么在内存中存储很多字符串就不会有问题。如果它们很大,则需要开始考虑一种将数据存储到内存之外的方法(存储在文件或数据库中)。
- 最后两行代码在做什么?(不是印刷品)
由于您拥有next_link = data['@odata.nextLink']
,因此我认为数据是字典。字典有一个get method。它返回提供的键的值。
如果字典中没有这样的键,则默认情况下,它返回None
,与使用方括号表示法获取键的值形成对比,如果键不在字典中,则返回KeyError
如果请求的键不在词典中,您还可以指定要返回的值。在示例中,我已明确使用None
,但您不必这样做。
- 您的None在做什么?
只要表达式为真,while
语句就会重复执行代码块。
False
,None
,空字符串,空字典等都是“虚假的”,这意味着服务器不提供next_link
而我们的{{1} }变量为next_link
,循环中断。
您可以阅读有关真值测试in the docs的更多信息。
使用您的代码,我收到251条记录,直到1429年。我错过了 前250条记录。
正如我在1.中所说,在您的代码中,您没有将第一个响应中的数据附加到None
。
因此,您需要创建列表,将第一个响应数据附加到该列表,然后继续下一个请求。它应该看起来像这样:
list_to_store_all_sclices
您还需要考虑的是,使用代码创建字典列表。您可能需要考虑结果数据的结构,以及它如何影响您将来的需求和结果的使用。
,如果一次只能获取250个项目,并且仅使用下一页一次,那么您将只能获取接下来的250个元素,因此只能获取500个元素。通常不知道您可以先获得多少个元素,我最近用这种结构解决了这个问题
json_dict,links = self._retrieve_transactions_json()
output_list = parse_json_list(json_dict) # this is my function dont
while links['next'] and ctr < num_transactions: # if there is a next link keep going,get all accounts
json_dict,links = self._retrieve_transactions_json(links['next']) # ditto my class
output_list.extend(parse_json_list(json_dict)) # ditto above
在不断获得下一笔交易之前,我一直在这里进行下一步工作。希望此代码模式有所帮助。这里的要点是,每次获取data
时,您都将需要遍历data['next'] #next page
直到其为null或根据API规范返回的最后一页
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。