搞爬虫的朋友肯定都遇到过这种情况:代码刚跑起来没一会儿,就返回403或者超时了。这多半是目标网站把你的真实IP给拦了。这时候,给Scrapy配上代理IP就是最直接有效的办法。很多人觉得在Scrapy里配代理很难,其实只要搞懂了中间件的写法,真的是一看就会,今天咱们就来把这个事儿给说透。
为什么要在中间件里设置代理
Scrapy的架构设计得特别清晰,下载器中间件就像是一个关卡,所有的请求发出去之前,都得先经过这里。咱们在这个关卡里把请求头里的IP地址换成代理IP,目标网站看到的就是代理IP,而不是你本机的IP了。这样做的好处是,你不用在每个爬虫文件里去改代码,只要写一次中间件,所有的爬虫都能共用,省时省力,维护起来也方便。
手把手教你写代理中间件
写中间件其实就两步:先在middlewares.py文件里写好处理逻辑,再去settings.py里把它打开。咱们直接看代码,逻辑非常直白。
import requests
from scrapy import signals
class ProxyMiddleware(object):
def process_request(self, request, spider):
这里以从神龙HTTP获取代理IP为例,实际使用时替换为你自己的API链接
api_url = "你的神龙HTTP提取链接"
try:
response = requests.get(api_url, timeout=3)
proxy_ip = response.text.strip()
if proxy_ip:
把代理IP塞进请求里
request.meta['proxy'] = f"http://{proxy_ip}"
spider.logger.info(f"当前使用代理: {proxy_ip}")
except Exception as e:
spider.logger.error(f"获取代理失败: {e}")
代码里的逻辑很简单:先去神龙HTTP的API接口拿到代理IP,然后把请求的meta字典里的proxy字段设置成咱们拿到的代理地址就行了。这样这个请求发出去的时候,走的就是代理通道了。
在settings.py里激活中间件
写完中间件代码还不算完,Scrapy默认是不开启自定义中间件的,你得在settings.py里告诉它一声。找到DOWNLOADER_MIDDLEWARES这个配置项,把咱们刚才写的类加进去,并把优先级数字调小一点,确保它能优先执行。
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.ProxyMiddleware': 543,
其他默认的中间件可以注释掉或者排在后面
}
这里要注意,数字越小优先级越高。设置好之后,你的Scrapy项目就能自动走代理IP去请求目标网站了。
选对代理服务才能事半功倍
中间件代码写好了,能不能稳定跑起来,关键还得看用的代理IP质量行不行。这里给大家推荐咱们神龙HTTP。神龙HTTP是国内三大运营商正规授权的,有超3000万的代理资源储备,每个IP都经过严格筛选,可用率高达99.9%。而且支持HTTP/HTTPS/SOCKS5协议,兼容性极好,API接口能快速集成到Scrapy里。
不管你是做数据抓取还是市场研究,神龙HTTP都能提供合适的套餐。为了方便大家选择,我整理了一个简单的表格:
| 套餐类型 | 特点说明 | 适用场景 |
|---|---|---|
| 短效动态IP池 | 3-30分钟存活,3000万+资源每日更新,低延迟高并发 | 适合高频次、大规模的公开数据采集 |
| 长效静态IP池 | 1-24小时存活,每日去重10万+,纯净度高 | 适合需要较长时间保持同一IP的任务 |
| 固定IP池 | 基于高性能云主机,ISP正式分配,极高稳定性 | 适合IP需求量不大但追求极致稳定的业务 |
神龙HTTP还提供个人中心可视化数据统计,帮大家直观地掌握IP使用情况。如果遇到问题,技术团队提供724小时的支持服务,随时解答疑问,这点对新手特别友好。
常见问题QA
问:代理IP经常失效导致请求报错怎么办?
答:这种情况多半是用的短效IP过期了。你可以在中间件里加一个异常捕获逻辑,在process_exception方法里,如果遇到请求失败,就重新去API提取一个新的IP再试一次。选择神龙HTTP这种高连通率的服务商也能大大减少这种问题,他们的IP资源都是经过严格验证的。
问:怎么知道中间件里的代理到底有没有生效?
答:最简单的办法就是在中间件的process_request方法里加一行print,把request.meta.get('proxy')打印出来。或者在目标网站那边看看请求日志的IP是不是变了。神龙HTTP的个人中心有可视化数据统计,你能直观看到IP的使用情况和趋势,如果请求数对得上,那就说明生效了。


