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

Клиент HTTP Python с конвейерной обработкой запросов

Проблема: мне нужно отправить много HTTP-запросов на сервер. Я могу использовать только одно соединение (ограничение для неограниченного сервера). Время отклика сервера и латентность сети слишком высоки - я отстаю.

Обычно запросы не изменяют состояние сервера и не зависят от предыдущего запроса ответа. Поэтому моя идея состоит в том, чтобы просто отправить их друг на друга, выделить объекты ответа и зависеть от Content-Length: входящих ответов для подачи входящих ответов на объект ожидания следующего ожидания. Другими словами: Pipeline - запросы на сервер.

Это, конечно, не совсем безопасно (любой ответ без Content-Length: означает проблему), но мне все равно - в этом случае я всегда могу повторить любые запросы в очереди. (Безопасный способ состоял бы в том, чтобы дождаться заголовка перед отправкой следующего бита.Это могло бы помочь мне достаточно. Нет способа проверить заранее.)

Итак, в идеале я хочу, чтобы следующий клиентский код (который использует задержки клиентов для имитации латентности сети) запускается через три секунды.

Теперь для вопроса $64000: есть ли библиотека Python, которая уже делает это, или мне нужно перевернуть мою? В моем коде используется gevent; При необходимости я мог бы использовать Twisted, но стандартный пул соединений Twisted не поддерживает конвейерные запросы. Я также мог бы написать оболочку для некоторой библиотеки C, если это необходимо, но я бы предпочел собственный код.

#!/usr/bin/python

import gevent.pool
from gevent import sleep
from time import time

from geventhttpclient import HTTPClient

url = 'http://local_server/100k_of_lorem_ipsum.txt'
http = HTTPClient.from_url(url, concurrency=1)

def get_it(http):
    print time(),"Queueing request"
    response = http.get(url)
    print time(),"Expect header data"
    # Do something with the header, just to make sure that it has arrived
    # (the greenlet should block until then)
    assert response.status_code == 200
    assert response["content-length"] > 0
    for h in response.items():
        pass

    print time(),"Wait before reading body data"
    # Now I can read the body. The library should send at
    # least one new HTTP request during this time.
    sleep(2)
    print time(),"Reading body data"
    while response.read(10000):
        pass
    print time(),"Processing my response"
    # The next request should definitely be transmitted NOW.
    sleep(1)
    print time(),"Done"

# Run parallel requests
pool = gevent.pool.Pool(3)
for i in range(3):
    pool.spawn(get_it, http)

pool.join()
http.close()
4b9b3361

Ответ 1

Dugong является клиентом только для HTTP/1.1, который утверждает, что поддерживает реальную конвейерную обработку HTTP/1.1. В учебнике есть несколько примеров того, как его использовать, в том числе using темы и еще один с помощью asyncio.

Обязательно убедитесь, что сервер, с которым вы общаетесь, фактически поддерживает конвейерную обработку HTTP/1.1, некоторые серверы утверждают, что поддерживают HTTP/1.1, но не реализуют конвейерную обработку.

Ответ 2

Это не ответ на вопрос вашей библиотеки, но не могли бы вы использовать что-то в качестве селена и их selenium.webdriver.support.ui import WebDriverWait дождаться, когда ваши запросы будут обработаны в течение некоторого времени, а затем сделайте следующий шаг: сохраните ответ для последующего использования или отправьте следующий запрос, если у вас нет соответствующего ответа?
Использование этого интерфейса также позволит использовать прокси для обхода (разумно, в зависимости от вашего приложения и потребностей) лимит сервера (либо 3, либо 5 - большая скорость), если для этого соединения не требуется аутентификация.

Ответ 3

Кажется, вы используете python2.

Для python3 >= 3.5 вы можете использовать цикл async/wait См. asyncio

Кроме того, есть библиотека, построенная сверху для лучшего, более простого использования называемый Trio, доступный по адресу.


Еще одна вещь, о которой я могу думать, - это несколько потоков с замками. Я буду думать о том, как лучше объяснить это, или он может даже работать.