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
复用同一个 ClientSession 和 TCPConnector。
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 | 每次新建 ClientSession | TCPConnector(limit=1) + Connection: close |
| B | 复用 ClientSession | keepalive_timeout=30 |
| C-HTTP | 请求头 Proxy-Tunnel | headers={"Proxy-Tunnel": ...} |
| C-HTTPS | CONNECT 阶段注入 | proxy_headers={"Proxy-Tunnel": ...} |
错误排查
curl -x http://$PROXY_USERNAME:$PROXY_PASSWORD@$PROXY_HOST:$PROXY_PORT https://httpbin.org/ip
遇到 407 请核对凭据,429 降低并发,504 重试。aiohttp 的 ClientTimeout 务必设置,避免请求卡死。
需要企业代理方案?
我们可根据目标站点、并发规模与稳定性目标提供定制方案。