如果请求库(由 grequests 使用)None
作为响应返回(无论出于何种原因),grequests 允许您通过调用您创建的异常处理程序回调函数然后传递给map
.
从grequests.py
(在map
方法中):
for request in requests:
if request.response is not None:
ret.append(request.response)
elif exception_handler and hasattr(request, 'exception'):
ret.append(exception_handler(request, request.exception))
elif exception_handler and not hasattr(request, 'exception'):
ret.append(exception_handler(request, None))
else:
ret.append(None)
这里发生了什么?在这个块执行之前,grequests 将提出所有的请求,现在我们正在循环遍历结果。对于每个请求:
- 如果你得到一个
response
,返回那个。
- 如果注册了异常处理程序并且
request
定义了exception
,则调用该处理程序并将其传递给request
and exception
。
- 如果注册了异常处理程序并且
request
没有定义,则exception
调用处理程序并将request
.
- 如果
response
was None
,但没有注册处理程序,则返回None
最后一种情况会导致数据丢失,但可以通过使用正确处理异常的回调来预防。究竟exception_handler
是什么是你需要定义的东西,然后像这样包括:
response = grequests.map(request_getters, exception_handler=my_handler)
处理程序的工作取决于您,但也许这会有所帮助:
MAX_PARALLEL_REQUESTS = 2
links = [
'https://api.github.com/users?since=135',
'http://www.google.com',
'https://api.github.com/users?since=135',
'http://www.google.com'
]
def my_handler(request, exception):
links.append(request.url)
print(f"exception thrown by grequests: \n{exception}")
return request
while links:
a = (grequests.get(links.pop(0)) for _ in range(MAX_PARALLEL_REQUESTS))
p = grequests.map(a, exception_handler=my_handler)
print(p)
links
这是在循环的每次迭代中从列表中弹出固定数量的 URL while
。如果这些请求中的任何一个失败,my_handler
则调用,它将失败的 URL 添加回links
列表以进行重新处理。