Подтвердить что ты не робот

Используя grequests, чтобы заставить несколько тысяч получить запросы к sourceforge, получите "Максимальное количество попыток превышено с помощью url"

Я очень новичок во всем этом; Мне нужно получить данные по нескольким тысячам проектов sourceforge на бумаге, которую я пишу. Все данные доступны в формате json по адресу http://sourceforge.net/api/project/name/[project name]/json. У меня есть список из нескольких тысяч этих URL, и я использую следующий код.

import grequests
rs = (grequests.get(u) for u in ulist)
answers = grequests.map(rs)

Используя этот код, я могу получить данные для любых 200 или около того проектов, которые мне нравятся, т.е. rs = (grequests.get(u) for u in ulist[0:199]) работает, но как только я перехожу к этому, все попытки выполняются с помощью

ConnectionError: HTTPConnectionPool(host='sourceforge.net', port=80): Max retries exceeded with url: /api/project/name/p2p-fs/json (Caused by <class 'socket.gaierror'>: [Errno 8] nodename nor servname provided, or not known)
<Greenlet at 0x109b790f0: <bound method AsyncRequest.send of <grequests.AsyncRequest object at 0x10999ef50>>(stream=False)> failed with ConnectionError

Тогда я не могу делать больше запросов до тех пор, пока не закрою python, но как только я перезапущу python, я могу сделать еще 200 запросов.

Я пробовал использовать grequests.map(rs,size=200), но это ничего не делает.

4b9b3361

Ответ 1

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

В моем случае это не было ограничение скорости на целевом сервере, но что-то гораздо проще: я не закрыл явно ответы, поэтому они не открывали сокет, а в процессе python закончились файловые дескрипторы.

Мое решение (не знаю точно, какой из них исправил проблему - теоретически любой из них должен был):

  • Установите stream=False в grequests.get:

    rs = (grequests.get(u, stream=False) for u in urls)
    
  • Вызов явно response.close() после чтения response.content:

    responses = grequests.map(rs)
    for response in responses:
          make_use_of(response.content)
          response.close()
    

Примечание. просто уничтожить объект response (присвоение ему None, вызов gc.collect()) недостаточно - это не закрыло обработчики файлов.

Ответ 2

Это можно легко изменить, чтобы использовать любое количество подключений, которое вы хотите.

MAX_CONNECTIONS = 100 #Number of connections you want to limit it to
# urlsList: Your list of URLs. 

results = []
for x in range(1,pages+1, MAX_CONNECTIONS):
    rs = (grequests.get(u, stream=False) for u in urlsList[x:x+MAX_CONNECTIONS])
    time.sleep(0.2) #You can change this to whatever you see works better. 
    results.extend(grequests.map(rs)) #The key here is to extend, not append, not insert. 
    print("Waiting") #Optional, so you see something is done.