如何错开异步 API 调用以防止使用 grequests 库进行最大重试?

Posted

技术标签:

【中文标题】如何错开异步 API 调用以防止使用 grequests 库进行最大重试?【英文标题】:How to stagger asynchronous API calls to prevent Max retries with grequests library? 【发布时间】:2019-01-30 03:31:29 【问题描述】:

我有一个大约 250K 的 URL 列表,用于我需要检索的 API。

我使用grequests 制作了一个类,它完全按照我想要的方式工作,但我认为它工作得太快了,因为在运行了整个 URL 列表后我得到了错误:

Problem: url: HTTPSConnectionPool(host='url', port=123): Max retries exceeded with url: url (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x38f466c18>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known',))

到目前为止的代码:

import grequests

lst = ['url','url2',url3']

class Test:
    def __init__(self):
        self.urls = lst

    def exception(self, request, exception):
        print ("Problem: : ".format(request.url, exception))

    def async(self):
        return grequests.map((grequests.get(u) for u in self.urls), exception_handler=self.exception, size=5)


    def collate_responses(self, results):
        return [x.text for x in results]

test = Test()
#here we collect the results returned by the async function
results = test.async()

如何降低代码速度以防止出现“最大重试次数错误”?或者更好的是如何将我拥有的列表分块并以块的形式传递 URL?

在 mac 上使用 python3.6。

编辑:

问题不重复,必须将许多 URL 传递到同一个端点。

【问题讨论】:

Max retries exceeded with URL的可能重复 @klanmiko 不是重复的,需要传入一个 URL 列表而不仅仅是一个 【参考方案1】:

尝试用循环替换 greqeusts.map 并添加睡眠

for u in self.urls:
  req = grequests.get(u)
  job = grequests.send(req)
  sleep(5)

similar issue resolved with sleep

【讨论】:

我在函数 async 中添加了您的行。这看起来对吗? def async(self): #return grequests.map((grequests.get(u) for u in self.urls), exception_handler=self.exception, size=5) for u in self.urls: req = grequests.get(u) job = grequests.send(req) time.sleep(1) 还有你为什么用grequests.send

以上是关于如何错开异步 API 调用以防止使用 grequests 库进行最大重试?的主要内容,如果未能解决你的问题,请参考以下文章

委派同步 WCF 调用以启动异步进程

根据 API 的响应异步更新进度条

SwiftUI:如何在搜索栏的文本更改时触发 api 调用以检索数据源

如何在 React 应用程序中使用 JEST 测试向 api 发出 axios 请求的异步函数

gcc / Linux:挂钩exit()调用以防止退出

如何构造循环API调用以使JSON结果可用?