Python 爬虫用代理 IP 的 6 个实用技巧(附代码示例)
做 Python 爬虫开发,代理 IP 是绕不开的话题。我在爬虫项目里踩过不少代理坑,总结出这6个实用技巧,附带可直接复用的代码示例。
技巧一:用 httpbin 验证代理可用性
在把代理投入生产环境之前,先用 httpbin 做一轮快速验证。httpbin.org 会原样返回你的请求信息,非常适合用来检查代理是否生效。
import requests
def test_proxy(proxy_url):
"""验证代理是否可用"""
proxies = {"http": proxy_url, "https": proxy_url}
try:
resp = requests.get("https://httpbin.org/ip", proxies=proxies, timeout=10)
if resp.status_code == 200:
ip = resp.json().get("origin", "unknown")
print(f"代理可用,出口IP: {ip}")
return True
except Exception as e:
print(f"代理不可用: {e}")
return False
# 使用示例
test_proxy("http://username:password@proxy-host:port")
这个函数有两个作用:一是确认代理能正常转发请求,二是查看代理的出口 IP 地址,验证是否符合预期的地域。
技巧二:设置合理的超时和重试策略
代理请求的响应时间波动较大,超时设置过短会导致大量误判,过长又会拖慢整体进度。
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
session = requests.Session()
# 配置重试策略
retry = Retry(
total=3,
backoff_factor=1, # 重试间隔: 1s, 2s, 4s
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["GET", "POST"]
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)
# 设置超时:连接5秒,读取15秒
response = session.get(
"https://target-site.com/data",
proxies={"http": proxy_url, "https": proxy_url},
timeout=(5, 15)
)
这里的超时用了元组格式 (connect_timeout, read_timeout),分别控制连接建立和数据读取的超时时间。重试策略针对服务器错误和限流状态码自动重试,避免因为偶发问题丢弃有效代理。
技巧三:Scrapy 中优雅集成隧道代理
Scrapy 的代理配置比 requests 稍微复杂一些,但用对方法后非常省心。
在 settings.py 中配置:
# 隧道代理配置
PROXY_URL = "http://username:password@tunnel.wukongdaili.com:port"
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 100,
}
# 在 spider 中设置代理
class MySpider(scrapy.Spider):
name = "example"
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
url,
meta={'proxy': PROXY_URL},
callback=self.parse
)
如果用的是隧道代理,每次请求 Scrapy 会自动通过隧道服务器获取新的出口 IP,无需手动轮换。
技巧四:用 aiohttp 做高并发代理请求
当采集量达到万级时,同步请求的效率瓶颈会非常明显。aiohttp 的异步能力可以把代理请求的吞吐量提升一个数量级。
import aiohttp
import asyncio
async def fetch_with_proxy(session, url, proxy):
try:
async with session.get(url, proxy=proxy, timeout=aiohttp.ClientTimeout(total=15)) as resp:
return await resp.text()
except Exception as e:
return f"Error: {e}"
async def main():
proxy = "http://username:password@proxy-host:port"
urls = ["https://httpbin.org/ip"] * 10 # 模拟10个并发请求
async with aiohttp.ClientSession() as session:
tasks = [fetch_with_proxy(session, url, proxy) for url in urls]
results = await asyncio.gather(*tasks)
for i, result in enumerate(results):
print(f"请求 {i+1}: {result[:100]}...")
asyncio.run(main())
并发数不是越高越好,需要根据代理服务商的并发上限和目标网站的承载能力做调整。建议从 20-50 并发开始逐步测试。
技巧五:建立代理 IP 质量监控
在生产环境中,代理 IP 的质量会随时间波动。建立一个简单的监控机制,可以及时发现问题。
import time
import statistics
class ProxyMonitor:
def __init__(self, proxy_url):
self.proxy_url = proxy_url
self.response_times = []
self.success_count = 0
self.total_count = 0
def check(self):
"""单次健康检查"""
start = time.time()
try:
resp = requests.get(
"https://httpbin.org/ip",
proxies={"http": self.proxy_url, "https": self.proxy_url},
timeout=10
)
elapsed = time.time() - start
self.response_times.append(elapsed)
self.success_count += 1
return resp.status_code == 200
except Exception:
return False
finally:
self.total_count += 1
def get_stats(self):
"""返回统计数据"""
success_rate = self.success_count / self.total_count if self.total_count else 0
avg_time = statistics.mean(self.response_times) if self.response_times else 0
return {
"success_rate": f"{success_rate:.1%}",
"avg_response": f"{avg_time:.2f}s",
"total_requests": self.total_count
}
建议每 100 次请求做一次健康检查,如果成功率低于 90% 或平均响应时间超过 3 秒,考虑切换代理供应商。
技巧六:处理代理认证和特殊协议
有些代理服务需要用户名密码认证,有些只支持 HTTP,有些支持 SOCKS5。认证方式不对是最常见的"代理用不了"的原因。
# HTTP 代理认证(用户名密码在 URL 中)
proxy_auth = "http://user:pass@proxy-host:port"
# 使用 requests 的代理认证参数
proxy_host = "http://proxy-host:port"
auth = ("user", "pass")
response = requests.get(
"https://target-site.com",
proxies={"http": proxy_host, "https": proxy_host},
auth=auth,
timeout=10
)
# SOCKS5 代理(需要安装 requests[socks])
# pip install requests[socks]
socks_proxy = "socks5://user:pass@proxy-host:port"
response = requests.get("https://target-site.com", proxies={"http": socks_proxy, "https": socks_proxy})
进阶建议:何时该从免费代理升级到付费代理
如果你正在用免费代理做项目,遇到以下情况说明该升级了:
成功率低于 70%,说明免费代理的可用率太低(通常在 30%-60%),大量时间浪费在重试上。响应时间超过 5 秒的慢代理不仅拖慢采集进度,还可能触发目标网站的超时封禁。IP 被频繁封禁意味着代理的 IP 被多人共用,早就上了目标网站的黑名单。当项目从实验走向生产,稳定的 SLA 保障就成为刚需。
付费代理服务如 悟空代理的隧道代理 或 独享代理 IP 方案,提供高可用率的 IP 资源和完善的技术支持,可以把代理相关的故障时间减少 90% 以上。
写在最后
代理 IP 不是配上去就完了的事。合理的超时重试、健康监控、并发控制,才是保证爬虫稳定运行的关键。把这 6 个技巧用到你的项目里,代理相关的故障率会明显下降。
如果你的项目正面临代理不稳定、IP 被封、并发不够等问题,可以了解一下 悟空代理 的解决方案,覆盖隧道代理、独享代理、住宅代理等多条产品线,快速解决你的代理难题。