1

例子:

下面的代码能够通过 grequests 获得多个 Web 结果,但是为什么它会因“进行简单的 api 调用”而失败

代码:

import grequests

links = [
    'https://api.github.com/users?since=135',
    'http://www.google.com',
    'https://api.github.com/users?since=135',
    'http://www.google.com'
]

a = (grequests.get(i) for i in links)
p = grequests.map(a)
print(p)

为什么输出不是:(响应 [200],响应 [200],响应 [200],响应 [200]

但是:(无,响应 [200],无,响应 [200]

...只是故意跳过api调用):

4

2 回答 2

0

如果请求库(由 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,则调用该处理程序并将其传递给requestand exception
  • 如果注册了异常处理程序并且request 没有定义,则exception调用处理程序并将request.
  • 如果responsewas 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列表以进行重新处理。

于 2020-12-05T03:50:10.573 回答
-2

最后,我意识到我所需要的只是用循环而不是使用 grequests 对其进行硬编码。

这里

import requests, time

links = [
    'https://api.github.com/users?since=135',
    'http://www.google.com',
    'https://api.github.com/users?since=135',
    'http://www.google.com'
]

sd = []

for i in links:
    try:
        d = requests.get(i)
        time.sleep(1)
        sd.append(d)
    except:
        sd.append(False)

print(sd)

#note that time.sleep(*) is only optional.

...不知道为什么 grequests 会这样。

于 2019-01-06T05:38:42.307 回答