Почему запросы "API" возвращают "Нет" в запросах, в то время как "обычная очистка веб-страниц" дает ответ 200

ПРИМЕР:

Приведенный ниже код способен получить несколько веб-результатов с помощью греквестов, но почему на самом деле он терпит неудачу с "совершением простых вызовов 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 по назначению):

1 ответ

Если библиотека запросов (используемая grequests) возвращает Noneв качестве ответа (по любой причине) grequests позволяет вам обрабатывать это так, как вы хотите, вызывая функцию обратного вызова обработчика исключений, которую вы создаете, а затем переходите к map.

Из grequests.pymap метод):

    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 и exception.
  • Если обработчик исключений зарегистрирован и request не имеет exception определены, вызовите обработчик и передайте ему request.
  • Если response было None, но обработчик не зарегистрирован, возврат None

Последний случай приводит к потере данных, но ее можно предотвратить с помощью обратного вызова, который правильно обрабатывает исключение. Что именно exception_handler does - это то, что вам нужно определить, а затем включить следующее:

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)

Это выдает фиксированное количество URL-адресов из links перечислить каждую итерацию whileпетля. Если какой-либо из этих запросов не удастся, my_handler вызывается, который добавляет неудачный URL обратно в links список для переработки.

В конце концов я понял, что все, что мне нужно, это жестко закодировать его с помощью циклов, а не с помощью греквестов.

Вот

:

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.

... не знаю, почему Грекест ведет себя так.

Другие вопросы по тегам