做爬虫最怕突然IP被封,无法继续进行工作。就像有的人总去超市试吃,结果被认出来了直接拉黑了不让进。后面再想进去只能"变脸"了,代理IP就像一个"面具库",让你想变就变,只不过手动切换效率太低,我们今天来讨论下如何用python实现自动切换IP代理。
一、随机切换法:每次请求都随机选代理
这是最基础的切换IP代理方式,也是最常用的方式。准备一个代理IP池,每次从中随机获取一个代理IP来使用,就像每次出门都随机选一件外套一样。
import requests
import random
# 代理池(假设有一个IP池,也可以直接从站大爷购买)
proxy_pool = [
{"http": "http://123.45.67.89:80808"},
{"https": "http://112.89.33.21:31288"},
{"https": "http://119.188.77.66:88688"}
# ... 可以继续添加更多代理IP
]
# 目标URL
url = "https://www.zdaye.com"
# 连续请求5次
for _ in range(5):
proxy = random.choice(proxy_pool)
try:
response = requests.get(url, proxies=proxy, timeout=5)
print(f"成功使用 {proxy} 获取数据")
except Exception as e:
print(f"代理 {proxy} 失效,自动跳过。错误信息:{e}")
这种方法的优点就是实现起来很简单,5分钟就能上手;缺点也很明显,就是可能会随机到失效代理,或者已经使用过的代理,需要配合代理IP检测和筛选程序来优化一下。
二、智能容错法:失败自动换代理
代理IP不是100%有效,或者说在不同的业务里,在不同的网络环境下,成功率是不一样的,当遇到某个请求失败的时候,就自动切换下一个代理IP,就像自动驾驶一样,遇到障碍就自动变道。
import requests
from itertools import cycle
class ProxyRotator:
def __init__(self, proxies):
self.proxies = cycle(proxies) # 创建循环迭代器
def get_page(self, url):
for _ in range(len(self.proxies)):
current_proxy = next(self.proxies)
try:
# 注意:requests.get 的 proxies 参数需要传入一个字典,而不是字符串
resp = requests.get(url, proxies=current_proxy, timeout=8)
return resp.text
except Exception as e:
print(f"{current_proxy} 请求失败,原因:{str(e)}")
raise Exception("所有代理均已失效")
# 使用示例
proxies = [{"https": f"http://proxy{i}:8080"} for i in range(10)]
rotator = ProxyRotator(proxies)
# 目标URL
url = "https://www.zdaye.com"
print(rotator.get_page(url))
这种方法的优点就是遇到失效的代理IP可以自动切换下一个代理IP,可以无限次重试,爬虫工作更顺畅;缺点就是需要维护有效代理IP池。
三、专业工具法:使用ProxyPool中间件
对于大型项目,推荐使用现成的代理管理工具。比如配合Scrapy框架:
# settings.py 配置
DOWNLOADER_MIDDLEWARES = {
'scrapy.downloadermiddlewares.retry.RetryMiddleware': 90,
'scrapy_proxy_pool.middlewares.ProxyPoolMiddleware': 100,
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
}
PROXY_POOL_ENABLED = True # 启用代理池
PROXY_POOL_URL = 'http://your-proxy-pool-service:5010' # 自建代理池API
# 爬虫代码无需任何修改,自动轮换代理
class MySpider(scrapy.Spider):
name = 'auto_proxy_spider'
start_urls = ['https://www.zdaye.com']
def parse(self, response):
# 解析逻辑...
# 示例:提取页面标题
title = response.css('title::text').get()
print(f"页面标题: {title}")
需要先安装代理池服务:
pip install scrapy-proxy-pool
docker run -p 5010:5010 ghcr.io/reproxy/proxypool
这个方法的优点就是可以全自动管理,可以管理量大的代理IP池,几万十几万都不在话下;缺点就是需要额外部署服务,大型项目可以考虑。
四、各方案怎么选?(对比表格)
建议新手从方案一开始练手,日均百万级数据采集就用方案三。具体怎么选,就看自己的业务规模了。
最后提醒:不要过度频繁访问目标网站,再好的代理IP也架不住每秒100次的暴力抓取。控制节奏、随机延时、配合User-Agent轮换,才能让爬虫工作持续稳定的进行。