import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# ============ 创建带连接池和重试机制的Session ============
def create_session():
    session = requests.Session()

    # 连接池设置: pool_connections 是主机数, pool_maxsize 是总连接数
    adapter = HTTPAdapter(
        pool_connections=10,
        pool_maxsize=50,
        max_retries=Retry(
            total=3,             # 总重试次数
            backoff_factor=0.5,  # 重试间隔时间指数退避
            status_forcelist=[500, 502, 503, 504]
        )
    )
    session.mount("http://", adapter)
    session.mount("https://", adapter)

    session.headers.update({
        "User-Agent": "DataFetcher/1.0"
    })
    return session

一、参数含义(requests → urllib3)

参数名 作用 默认值 说明
pool_connections 连接池中能同时维护的目标主机数 10 相当于最多同时为多少个不同域名创建连接池。
pool_maxsize 每个主机连接池中可同时保持的最大连接数 10 相当于每个主机最多允许多少并发请求共享连接。

主机定义规则
requests 以 “host:port” 识别主机。例如:

https://web1.com:443 和 https://web1.com:8080 视为不同主机。

确保URL中的端口明确(或使用默认端口)。

简单理解:

1)如果你只访问一个域名(例如 web1.com),pool_maxsize 比较重要;

2)如果你同时访问多个域名(web1、web2、web3...),pool_connections 控制全局的“主机桶数”。

二、默认值及其问题

requests 默认值是:

pool_connections=10 pool_maxsize=10

这对单线程或低并发爬取是可以的,但当你:

  • 启动 20 个线程

  • 并发访问同一网站;

  • 或多个不同网站;

就会发现:

  • 有的线程要“等连接”,因为池已满;

  • 性能下降明显;

  • TCP connection 不够复用。

三、最小合理配置(经验值)

并发线程数 建议配置
1–5 pool_connections=5, pool_maxsize=5
10–20 pool_connections=10, pool_maxsize=20
30–50 pool_connections=20, pool_maxsize=50
100+ pool_connections=50, pool_maxsize=100

对于你这种 20线程并发访问 web1 + web2 的场景:

adapter = HTTPAdapter(pool_connections=10, pool_maxsize=20)

已经完全足够,不需要太大

四、配置原则总结

1)pool_maxsize ≥ 线程数

这样不会出现线程等待连接的情况。

2)pool_connections ≈ 访问网站的数量

如果你固定访问 web1、web2,各自都建一个 Session,那么 pool_connections=10 甚至 2 都可以。

3)太大没必要

超出并发量太多只会浪费内存,不会提速。

4)一个 Session 共用连接池

不要频繁创建新的 Session,否则连接池复用会失效。

五、实例推荐配置(你当前场景)

你:

  • 启动 20 线程

  • 两个域名(web1/web2)

  • 每个域名独立 Session

推荐如下:

web1_session = create_session("web1", max_pool=20) 
web2_session = create_session("web2", max_pool=20)

create_session 内部:

HTTPAdapter(pool_connections=10, pool_maxsize=max_pool)

这样既高效又稳妥。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐