Requests хорошо, но grequests лучше. Я не знаю лучше, эффективней библиотеку, которая умеет быстро и элегантно выполнять HTTP-запросы нежели requests, данная библиотека — несомненный лидер, в данном плане.

Но так как с асинхронностью, у неё хромает, выполнять асинхронные запросы возможно с использованием threading или gevent.

Написал grequests, тот же автор что и написал requests. Только с использованием gevent + requests. Не буду долго мусолить тему, дам вам подробную информацию о данной библиотеки.

Grequestsявляется асинхронной обёрткой над обычной requests.

Сделаем обычный POST-запрос на множество url-адресов:

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.imap(rs, size=16) 
    print(r[0].status_code, r[0].url)

Все довольно просто, импортируется библиотека, открывается файл на чтение, создается список, переменной params присваивается значения a:b, c:d.

Далее создаем переменную rs которая будет отвечать за сам POST-запрос, для переменной r создаем grequests.map([rs], size=является асинхронным значением, чем больше значение тем быстрее будут выполнятся http-запросы, правда больше 16 не имеет смысла ставить).

Теперь так как мы передали все аргументы в переменную r, то есть в grequests.imap() мы можем взаимодействовать с данной переменной как в обычном requests.

И последним шагом нам нужно вывести все status code, url address, также rs выступает списком, это мы делаем для того чтоб не было ошибок индексации по типу:

TypeError: 'Response' object does not support indexing

Если у вас все ровно вылезает traceback с данной ошибкой, предлагаю вариант:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r[0].status_code, r[0].url)


Теперь и к переменной r мы будем обращаться как к списку, дабы избежать ошибок индексации.
Основные шаги, мы сделали. Можете «ДУДОСИТЬ» сервера. Хотя, заоблачной асинхронностью данная библиотека не обладает. Это можно приглянуть к Aiohttp.

Ещё хотел бы поговорить о исключениях в grequests. Так как grequests не использует error-классы из requests, а делает следующим образом:

def send(self, **kwargs):
    """
    Prepares request based on parameter passed to constructor and optional      ``kwargs```.
    Then sends request and saves response to :attr:`response`

    :returns: ``Response``
    """
    merged_kwargs = {}
    merged_kwargs.update(self.kwargs)
    merged_kwargs.update(kwargs)
    try:
        self.response = self.session.request(self.method,
                                            self.url, **merged_kwargs)
    except Exception as e:
        self.exception = e
        self.traceback = traceback.format_exc()
    return self

Мы ловим при помощи exception_handler:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 
    # print(str(exception)) 


Полный исходный код:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.post(u, data=params) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r.status_code, r.url)


Так мы сможем с полной уверенностью отлавливать ошибки.

С GET-запросами все так-же просто как и с POST-запросами:

def exception_handlerr(request, exception):
    print("Request failed", request.url) 

import grequests 
with open("C:\\path\\urls.txt") as werewolves: 
    array = [row.strip() for row in werewolves]

params = {'a':'b', 'c':'d'}
rs = [grequests.get(u) for u in array]
for r in grequests.map([rs], size=16, exception_handler=exception_handlerr) 
    print(r.status_code, r.url)

> Исходный код grequests
> Документация по requests

Удачного вам дня!

Комментарии (4)


  1. tytar
    06.08.2017 00:05
    +1

    Какие проблемы решает grequest, которые не способно решить aiohttp? В чем профит этой библиотеки? Хотелось бы прочесть в статье.


    1. Merlen_Gross
      06.08.2017 02:39

      Я не автор, но, как минимум, не используется asyncio, что, в свою очередь, подразумевает отсутствие необходимости в асинхронных функциях. Плюс, конечно, всеми любимый API requests. Бесспорно, aiohttp или тот же Tornado лучше подходит для подобных задач, но всё же. Такой вот анализ.


  1. tmnhy
    06.08.2017 10:08
    +1

    Я не знаю лучше, эффективней библиотеку, которая умеет быстро и элегантно выполнять HTTP-запросы нежели requests, данная библиотека — несомненный лидер, в данном плане.

    Отдавая должное requests, это уже вчерашний день. Присоединяюсь к рекомендациям aiohttp, HTTP-запросы ещё эффективнее и элегантнее.


  1. variable
    07.08.2017 03:21

    >>Если у вас все ровно вылезает traceback
    когда все ровно, traceback не вылезает