为什么“ API”请求在grequests中返回“ None”,而“普通网页抓取”却给出200响应

时间:2019-01-05 16:35:15

标签: python api python-requests grequests

示例:

下面的代码能够通过grequests获得多个网络结果,但是为什么它实际上会因“ 进行简单的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调用):

2 个答案:

答案 0 :(得分:0)

最后,我意识到我所需要的只是使用循环而不是使用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.

...不知道为什么grequest表现得如此。

答案 1 :(得分: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,请调用该处理程序并将其传递给requestexception
  • 如果注册了异常处理程序并且request 没有定义了exception,请调用该处理程序并将其传递给request
  • 如果responseNone,但没有注册处理程序,则返回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循环的每次迭代中,都会从while列表中弹出固定数量的URL。如果这些请求中的任何一个失败,则将调用my_handler,这会将失败的URL添加回links列表中以进行重新处理。