Как включить режим async запросов? - программирование
Подтвердить что ты не робот

Как включить режим async запросов?

для этого кода:

import sys

import gevent
from gevent import monkey

monkey.patch_all()

import requests
import urllib2

def worker(url, use_urllib2=False):
    if use_urllib2:
        content = urllib2.urlopen(url).read().lower()
    else:
        content = requests.get(url, prefetch=True).content.lower()
    title = content.split('<title>')[1].split('</title>')[0].strip()

urls = ['http://www.mail.ru']*5

def by_requests():
    jobs = [gevent.spawn(worker, url) for url in urls]
    gevent.joinall(jobs)

def by_urllib2():
    jobs = [gevent.spawn(worker, url, True) for url in urls]
    gevent.joinall(jobs)

if __name__=='__main__':
    from timeit import Timer
    t = Timer(stmt="by_requests()", setup="from __main__ import by_requests")  
    print 'by requests: %s seconds'%t.timeit(number=3)
    t = Timer(stmt="by_urllib2()", setup="from __main__ import by_urllib2")  
    print 'by urllib2: %s seconds'%t.timeit(number=3)
    sys.exit(0)

этот результат:

by requests: 18.3397213892 seconds
by urllib2: 2.48605842363 seconds

в sniffer он выглядит так:

описание: первые 5 запросов отсылаются библиотекой запросов, следующие 5 запросов отправляются библиотекой urllib2. красный - это время, когда работа замерзала, темная - при получении данных... wtf?!

Как это возможно, если библиотека сокетов пропатчена, а библиотеки должны работать одинаково? Как использовать запросы без request.async для асинхронной работы?

4b9b3361

Ответ 1

Извините Кеннет Рейц. Его библиотека прекрасна.

Я глуп. Мне нужно выбрать патч обезьяны для httplib следующим образом:

gevent.monkey.patch_all(httplib=True)

Поскольку исправление для httplib по умолчанию отключено.

Ответ 2

Как заметил Кеннет, еще одна вещь, которую мы можем сделать, это позволить модулю requests обрабатывать асинхронную часть. Я внес изменения в свой код соответственно. И снова для меня результаты показывают, что модуль requests работает лучше, чем urllib2

Выполнение этого означает, что мы не можем "прокрутить" часть обратного вызова. Но это должно быть хорошо, потому что основной выигрыш должен ожидаться только с HTTP-запросами из-за задержки запроса/ответа.

import sys

import gevent
from gevent import monkey

monkey.patch_all()

import requests
from requests import async
import urllib2

def call_back(resp):
    content = resp.content
    title = content.split('<title>')[1].split('</title>')[0].strip()
    return title

def worker(url, use_urllib2=False):
    if use_urllib2:
        content = urllib2.urlopen(url).read().lower()
        title = content.split('<title>')[1].split('</title>')[0].strip()

    else:
        rs = [async.get(u) for u in url]
        resps = async.map(rs)
        for resp in resps:
            call_back(resp) 

urls = ['http://www.mail.ru']*5

def by_requests():
    worker(urls)
def by_urllib2():
    jobs = [gevent.spawn(worker, url, True) for url in urls]
    gevent.joinall(jobs)

if __name__=='__main__':
    from timeit import Timer
    t = Timer(stmt="by_requests()", setup="from __main__ import by_requests")
    print 'by requests: %s seconds'%t.timeit(number=3)
    t = Timer(stmt="by_urllib2()", setup="from __main__ import by_urllib2")
    print 'by urllib2: %s seconds'%t.timeit(number=3)
    sys.exit(0)

Вот один из моих результатов:

by requests: 2.44117593765 seconds
by urllib2: 4.41298294067 seconds

Ответ 4

Я запустил ваш код на своей машине (python 2.7.1, gevent 0.13.0, requests 0.10.6). Оказалось, что при использовании модуля запросов время всегда было хорошим вторым или вторым. Какие версии вы используете? Обновление может просто решить проблему для вас.

by requests: 3.7847161293 seconds
by urllib2: 4.92611193657 seconds

by requests: 2.90777993202 seconds
by urllib2: 7.99798607826 seconds

Ответ 5

Из запросов doc Блокировка или неблокирование:

Если вас беспокоит использование блокировки ввода-вывода, есть много проектов, которые объединяют запросы с одной из инфраструктур асинхронности Python. Два отличных примера: grequests и requests-futures.