Python 配代理:requests、httpx、aiohttp

作者:Mechelle Henderson · 发布:2026 年 9 月 7 日 · 阅读约 6 分钟

一句话总结: 三个库都支持带认证的代理,但写法不同。requests:一个 proxies 字典,凭据写进 URL。httpx:单数 proxy= 参数(不再是 proxies=)。aiohttp:一个纯代理 URL 加单独的 proxy_auth=BasicAuth(...)。把它们指向轮换住宅网关,改变粘性会话标记即可轮换 IP。

requests

最经典的客户端。把凭据写进代理 URL,传一个 proxies 字典 —— 用 Session 让代理对每次调用都生效:

import requests

PROXY = "http://YOUR_USERNAME:[email protected]:41080"

session = requests.Session()
session.proxies = {"http": PROXY, "https": PROXY}

r = session.get("https://ip.sb")
print(r.text.strip())   # 一个 Roam 住宅出口 IP

两个键用同一个 http:// URL 是有意为之:scheme 指的是代理自己的协议,不是目标的,所以它照样能正确代理你的 HTTPS 请求。

httpx(同步与异步)

现代 httpx 用单数 proxy= 参数。如果你在旧教程里见过 proxies=,它已经没了 —— 那个复数写法被移除了:

import httpx

PROXY = "http://YOUR_USERNAME:[email protected]:41080"

# 同步
with httpx.Client(proxy=PROXY) as client:
    print(client.get("https://ip.sb").text.strip())

# 异步 —— 同一个参数
import asyncio

async def main():
    async with httpx.AsyncClient(proxy=PROXY) as client:
        r = await client.get("https://ip.sb")
        print(r.text.strip())

asyncio.run(main())

要用 SOCKS5 而非 HTTP,装 httpx[socks] 并用 socks5:// URL。走 HTTP 不需要任何额外东西。

aiohttp

aiohttp 是个例外:它不能可靠地从代理 URL 读凭据。把代理写成纯 URL,凭据单独用 proxy_auth 传:

import aiohttp, asyncio

GATEWAY = "http://gw.roamproxy.com:41080"
AUTH = aiohttp.BasicAuth("YOUR_USERNAME", "YOUR_PASSWORD")

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get("https://ip.sb", proxy=GATEWAY, proxy_auth=AUTH) as resp:
            print((await resp.text()).strip())

asyncio.run(main())

aiohttp 原生只支持 HTTP 代理。如果你搜的是「aiohttp proxy socks5」,你需要单独的 aiohttp-socks 包 —— 裸 aiohttp 不做 SOCKS。走 Roam 的 HTTP 网关,上面这段就够了。

轮换 IP

用轮换住宅代理就没有代理列表要管。保持一个网关,改变用户名里的粘性会话标记 —— 每个不同会话就是一个不同的住宅出口 IP:

import itertools, requests

BASE_USER, PASSWORD = "YOUR_USERNAME", "YOUR_PASSWORD"
counter = itertools.count()

def proxy_for_new_ip():
    user = f"{BASE_USER}_session_{next(counter)}"
    url = f"http://{user}:{PASSWORD}@gw.roamproxy.com:41080"
    return {"http": url, "https": url}

for _ in range(3):
    r = requests.get("https://ip.sb", proxies=proxy_for_new_ip())
    print(r.text.strip())   # 每次一个不同的 IP

需要几个请求共用一个 IP 时(登录、翻页流程)就复用同一个标记;想换新 IP 就生成新的。粘性会话原理见什么是轮换代理,控速见如何避免被封

当纯 HTTP 客户端不够时

这些库发的是带 Python TLS 指纹的脚本请求。干净的住宅 IP 能解决信誉封锁,但目标若在给你的 TLS 握手打指纹,请求照样会被标记。这时用 curl_cffi 给请求一个浏览器级指纹;若页面确实需要 JavaScript,就用 Playwright 或 Puppeteer 驱动真浏览器走同一个代理。要针对具体防御选对层次,见如何绕过 Cloudflare

常见问题

Python requests 怎么设代理?

传一个 proxies 字典,凭据写在 URL 里:proxies = {"http": "http://user:[email protected]:41080", "https": "http://user:[email protected]:41080"},然后 requests.get(url, proxies=proxies)。两个键用同一个 http:// URL 是对的 —— scheme 指的是代理自己的协议,不是目标的,所以它照样能正确代理 HTTPS 目标。

httpx 里是 proxy 还是 proxies?

现在的 httpx 用单数 proxy= 参数:httpx.Client(proxy="http://user:[email protected]:41080")。旧的复数 proxies= 字典已被弃用并移除,所以用 proxies= 的教程都过时了。httpx.AsyncClient 用同样的 proxy= 参数。

aiohttp 怎么给代理做认证?

aiohttp 不能可靠地从代理 URL 读凭据。把代理写成纯 URL,凭据单独用 proxy_auth 传:session.get(url, proxy="http://gw.roamproxy.com:41080", proxy_auth=aiohttp.BasicAuth("user", "pass"))。aiohttp 原生也只支持 HTTP 代理 —— 要 SOCKS 得装 aiohttp-socks 包。

Python 里怎么在多个请求间轮换 IP?

用轮换住宅代理时,保持一个网关、改变用户名里的粘性会话标记。每个请求或每个客户端构建一个新用户名(如 USERNAME_session_5),每个不同会话对应一个不同的住宅出口 IP —— 不用维护代理列表。

上面每个客户端要的都是一个 host:port 代理加凭据 —— 正是 Roam 提供的。轮换住宅 $2/GB、静态住宅 $4/IP/月,支持 HTTP 和 SOCKS5,粘性会话可做每请求轮换。注册账号,拿 300MB 免费试用流量,让你的第一个脚本从住宅出口出去。