Пул соединений URLLib3 создает только один пул

В настоящее время я пытаюсь очистить сайт, но сайт не разрешает более 100 запросов для одного TCP-соединения. Итак, я попытался создать несколько пулов соединений для запросов. Я попробовал следующий код. Разве он не должен создавать 15 пулов соединений?

from urllib3 import HTTPConnectionPool
for i in range(15):
    pool = HTTPConnectionPool('ajax.googleapis.com', maxsize=15)
    for j in range(15):
        resp= pool.request('GET', '/ajax/services/search/web')
    pool.num_connections

pool.num_connection всегда печатает 1


person mj sunny    schedule 25.03.2015    source источник
comment
Ваш код делает несколько запросов, а не соединений, чего вы по-прежнему пытаетесь избежать. Выведите значение pool.num_requests, чтобы понять, что я имею в виду.   -  person BlackVegetable    schedule 26.03.2015
comment
@BlackVegetable я пытаюсь создать несколько TCP-соединений для одного и того же хоста. Любой пример был бы потрясающим   -  person mj sunny    schedule 26.03.2015


Ответы (2)


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

Теперь предположим, что мы запускаем код с использованием потоков, несколько запросов будут выполняться одновременно. В этом случае pool.num_connections будет больше 1:

from concurrent.futures.thread import ThreadPoolExecutor

from urllib3 import HTTPConnectionPool


pool = HTTPConnectionPool('ajax.googleapis.com', maxsize=15)

def send_request(_):
    pool.request('GET', '/ajax/services/search/web')
    print(pool.num_connections)


with ThreadPoolExecutor(max_workers=5) as executor:
    executor.map(send_request, range(5))
person darkheir    schedule 12.03.2021

Если вам нужно закрывать сокеты каждые 100 запросов, вам нужно будет сделать это вручную. Вот пример, который закрывает все сокеты каждые 5 запросов:

import urllib3
urllib3.add_stderr_logger() # This lets you see when new connections are made

http = urllib3.PoolManager()
url = 'http://ajax.googleapis.com/ajax/services/search/web'
for j in range(15):
    resp = http.request('GET', url)
    if j % 5 == 0:
        # Reset the PoolManager's connections.
        # This might be overkill if you need more granular control per-host.
        http.clear()

Вы можете сделать что-то подобное, используя HTTPConnectionPool и выполняя .close() перед заменой на новый. Я предпочитаю использовать PoolManager, когда это возможно (как правило, у него нет недостатков).

Если вы хотите максимально детализировать подключения, вы можете вручную удалить подключения из HTTPConnectionPool, используя pool._get_conn() и .close().

person shazow    schedule 26.03.2015
comment
Можно ли создать несколько соединений tcp одновременно для одного конкретного сервера с одного клиента. любая информация по этому поводу была бы очень полезна для меня. @shazow - person mj sunny; 26.03.2015
comment
Вы имеете в виду асинхронно? Если это так, вам нужно будет использовать некоторые примитивы валюты, такие как потоки или gevent. Указание maxsize, как вы сделали в своем вопросе, выделит столько возможных сокетов в пуле. - person shazow; 27.03.2015