1

目前我正在尝试抓取一个站点,但该站点不允许对一个 tcp 连接进行超过 100 个请求。所以,我尝试为请求创建多个连接池。我尝试了以下代码。它不应该创建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

4

2 回答 2

0

问题是请求是一个接一个地同步发出的。出于这个原因,池将始终使用相同的连接,而无需创建任何其他连接。

现在假设我们使用线程运行代码,多个请求将同时发出。在这种情况下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))
于 2021-03-12T09:55:15.277 回答
-1

如果您需要每 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(通常没有缺点)。

如果您想获得超级精细的连接,您可以手动将连接从HTTPConnectionPoolusingpool._get_conn().close()ing 中取出。

于 2015-03-26T04:27:30.457 回答