requests带代理需严格按{"http": "协议://地址", "https": "协议://地址"}格式传proxies字典,HTTP/HTTPS键必须同时指定且协议一致;带认证时URL需编码特殊字符;Flask/FastAPI代理池接口应返回随机可用代理JSON,启动及调用前均需HEAD轻量校验连通性、状态码、响应内容与Via头;自建代理池维护成本高,需细粒度日志追踪失效原因。

requests 怎么带代理发请求
Python 爬虫用代理,核心就是把 proxies 字典传给 requests.get() 或 requests.post()。不写对格式,直接报错或静默失效。
常见错误是只写 IP 不写协议,比如 {"http": "123.45.67.89:8080"} —— 这会让 HTTPS 请求走默认直连,HTTP 也可能被中间设备重定向后暴露真实 IP。
- 必须区分
http和https键:即使代理支持 HTTPS,requests默认也不会自动把 HTTPS 流量转给http://代理(除非代理明确声明支持 CONNECT) - 如果代理是 HTTP 类型(最常见),
https键也得填一样的地址,否则 HTTPS 请求不走代理 - 带认证的代理要写成
"http://user:pass@123.45.67.89:8080",URL 编码特殊字符(如@、:)容易漏掉
正确示例:
proxies = {
"http": "http://user:pass%40123@123.45.67.89:8080",
"https": "http://user:pass%40123@123.45.67.89:8080"
}
requests.get("https://httpbin.org/ip", proxies=proxies)
Flask/FastAPI 怎么暴露一个简单代理池接口
所谓“代理池接口”,本质就是一个返回随机可用代理的 HTTP 接口,不是转发流量的网关。别一上来就写异步转发,那是反向代理的事,和爬虫用的代理池无关。
最容易踩的坑是:把代理 IP 存内存列表就完事,结果没做可用性验证,返回的全是超时或 403 的代理,调用方直接卡死。
立即学习“Python免费学习笔记(深入)”;
- 启动时至少做一次预检:用
requests.head("https://httpbin.org", timeout=3)批量筛掉不可用代理 - 接口返回前再轻量校验(比如加个
timeout=1的 HEAD 请求),避免长时间堆积失效 IP - 别用全局 list 存代理——并发高时读写竞争,FastAPI 的
BackgroundTasks或 Flask 的线程安全队列更稳妥 - 返回格式建议统一为 JSON:
{"http": "http://...", "https": "http://..."},别省略https字段
代理池怎么判断 IP 是否还活着
代理失效不是非黑即白,而是分层退化:能连上但响应慢、返回 407 要认证、返回 403 但 headers 里有 X-Proxy-Status: blocked……只靠 status_code == 200 会漏判。
真正有效的健康检查得组合多个信号:
- 连接时间 > 3s 就标记为“待观察”,连续两次超时就踢出
- 响应 body 包含
"Your IP address is"(来自 httpbin)才算通过;如果返回的是登录页 HTML 或空 body,说明被拦截了 - 检查
response.headers.get("via")是否存在,没有可能根本没走代理(本地直连伪装) - 别用 GET 检查——有些代理对 GET 放行但 POST 拦截,HEAD 更轻量且语义合适
示例校验逻辑:
try:
r = requests.head("https://httpbin.org", proxies=p, timeout=2)
ok = (r.status_code == 200 and "Your IP address" in r.text)
except Exception:
ok = False
为什么自己搭代理池比直接买 API 更容易翻车
自建代理池最大的隐性成本不是代码,是维护节奏:IP 失效速度远快于你轮询的频率,而商用 API 背后是持续运营的 IP 库和自动替换策略。
如果你只是临时跑个脚本,或者目标网站反爬弱,真没必要自建——几行 proxies 配置 + 轮询几个免费代理站,比搭接口省心十倍。
一旦决定自建,最常被忽略的是日志粒度:不记录每次代理返回的 r.elapsed、r.status_code、r.headers,你就永远不知道是代理挂了,还是目标站加了新规则,还是自己代码拼错了 URL。










