Python aiohttp 隧道代理:异步并发四种 IP 控制场景

aiohttp 异步实现四种隧道代理场景,proxy_headers 参数在 CONNECT 阶段注入 Proxy-Tunnel 头支持 HTTPS。

亿牛云技术团队2026年5月19日1 分钟阅读

aiohttp 的异步优势

aiohttp 是 Python 最成熟的异步 HTTP 客户端/服务端框架。在代理场景中,它的 proxy_headers 参数可以在 CONNECT 阶段直接注入自定义头——与 httpx 类似,比 requests 简洁。

环境准备

export PROXY_HOST=t.16yun.cn
export PROXY_PORT=31111
export PROXY_USERNAME=your-username
export PROXY_PASSWORD=your-password
export PROXY_TUNNEL=python-aiohttp-demo-12345

场景 A:强制切换 IP

每次创建新的 ClientSession,禁用连接复用。

import asyncio, os, json
import aiohttp

host = os.getenv("PROXY_HOST", "t.16yun.cn")
port = os.getenv("PROXY_PORT", "31111")
user = os.getenv("PROXY_USERNAME", "user")
pwd = os.getenv("PROXY_PASSWORD", "password")

proxy = f"http://{host}:{port}"
proxy_auth = aiohttp.BasicAuth(user, pwd)

async def scenario_a():
    for i in range(1, 4):
        connector = aiohttp.TCPConnector(limit=1, limit_per_host=1)
        async with aiohttp.ClientSession(connector=connector) as session:
            async with session.get(
                "https://httpbin.org/ip",
                proxy=proxy, proxy_auth=proxy_auth,
                headers={"Connection": "close", "Proxy-Connection": "close"},
                timeout=aiohttp.ClientTimeout(total=15),
            ) as resp:
                data = await resp.json()
                print(f"请求 {i}: {data['origin']}")
            await asyncio.sleep(0.5)

asyncio.run(scenario_a())

场景 B:Keep-Alive 保持相同 IP

复用同一个 ClientSessionTCPConnector

async def scenario_b():
    connector = aiohttp.TCPConnector(limit=10, keepalive_timeout=30)
    async with aiohttp.ClientSession(connector=connector) as session:
        for i in range(1, 4):
            async with session.get(
                "https://httpbin.org/ip",
                proxy=proxy, proxy_auth=proxy_auth,
                headers={"Connection": "keep-alive", "Proxy-Connection": "keep-alive"},
                timeout=aiohttp.ClientTimeout(total=15),
            ) as resp:
                data = await resp.json()
                print(f"请求 {i}: {data['origin']}")
            await asyncio.sleep(0.2)

场景 C-HTTP:Proxy-Tunnel 固定 IP(HTTP 目标)

async def scenario_c_http():
    tunnel = os.getenv("PROXY_TUNNEL", "aiohttp-demo")
    for i in range(1, 4):
        async with aiohttp.ClientSession() as session:
            async with session.get(
                "http://httpbin.org/ip",
                proxy=proxy, proxy_auth=proxy_auth,
                headers={"Proxy-Tunnel": tunnel, "Connection": "keep-alive"},
                timeout=aiohttp.ClientTimeout(total=15),
            ) as resp:
                data = await resp.json()
                print(f"请求 {i}: {data['origin']}")
            await asyncio.sleep(0.2)

场景 C-HTTPS:Proxy-Tunnel 固定 IP(HTTPS 目标)

aiohttp 通过 proxy_headers 参数在 CONNECT 阶段注入 Proxy-Tunnel

async def scenario_c_https():
    tunnel = os.getenv("PROXY_TUNNEL", "aiohttp-demo")
    for i in range(1, 4):
        async with aiohttp.ClientSession() as session:
            async with session.get(
                "https://httpbin.org/ip",
                proxy=proxy, proxy_auth=proxy_auth,
                proxy_headers={"Proxy-Tunnel": tunnel},
                headers={"Connection": "keep-alive"},
                timeout=aiohttp.ClientTimeout(total=15),
            ) as resp:
                data = await resp.json()
                print(f"请求 {i}: {data['origin']} (HTTPS Proxy-Tunnel)")
            await asyncio.sleep(0.2)

proxy_headers 是 aiohttp 特有的参数,头会在 HTTPS CONNECT 握手时发送给代理服务器。requests 没有等效参数,需要用自定义 Adapter。

场景对比

场景aiohttp 实现关键 API
A每次新建 ClientSessionTCPConnector(limit=1) + Connection: close
B复用 ClientSessionkeepalive_timeout=30
C-HTTP请求头 Proxy-Tunnelheaders={"Proxy-Tunnel": ...}
C-HTTPSCONNECT 阶段注入proxy_headers={"Proxy-Tunnel": ...}

错误排查

curl -x http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_HOST:$PROXY_PORT https://httpbin.org/ip

遇到 407 请核对凭据,429 降低并发,504 重试。aiohttp 的 ClientTimeout 务必设置,避免请求卡死。

需要企业代理方案?

我们可根据目标站点、并发规模与稳定性目标提供定制方案。