Python 爬虫代理 IP 在 Scrapy 里怎么做成中间件-易代理

本站 · 2026-10-15 最新资讯 4

Scrapy 项目为什么不能每个请求手写代理

小脚本用 Requests,大项目用 Scrapy。Scrapy 本身是异步框架,下载器、中间件、管道各管各的。你要是在 Spider 里每个 Request 都手动塞 proxies,代码会又臭又长,还容易漏。

正确做法是在下载器中间件里统一注入。Python 爬虫代理 IP 一旦进 Scrapy 中间件,全项目所有请求都走同一套出口逻辑,后续换池子、加鉴权、做评分都不用改业务代码。

最基础的代理中间件

pythonclass ProxyMiddleware:
    proxy_url = "http://用户名:密码@网关地址:端口"

    def process_request(self, request, spider):
        request.meta["proxy"] = self.proxy_url

settings.py 里启用:

pythonDOWNLOADER_MIDDLEWARES = {    "myproject.middlewares.ProxyMiddleware": 350,
}

这样 Scrapy 发请求前会自动把 proxy 写进 meta。Python 爬虫代理 IP 的入口只需要维护这一个类,不用散落到各个 Spider。

动态网关和 IP 池的区别

有两种玩法。第一种是动态转发网关,Scrapy 永远连同一个网关地址,服务端每次换出口。这种最省心,代码里没有池子概念。

第二种是自己维护 IP 池,从 API 拉一批地址,放内存里随机取,失败了剔除,定时补。

pythonimport randomclass PoolProxyMiddleware:
    proxy_pool = []    def process_request(self, request, spider):        if not self.proxy_pool:            self.proxy_pool = load_proxy_list_from_api()

        proxy = random.choice(self.proxy_pool)
        request.meta["proxy"] = f"http://{proxy}"
        request.meta["_used_proxy"] = proxy

Python 爬虫代理 IP 用池子模式时,必须配套失败回收,不然坏地址越积越多,爬虫不是被目标站封死,是被自己的脏池子拖死。

响应里发现验证页要处理

Scrapy 里不能只看 status。200 也可能返回验证页。可以在 response 中间件里判断关键字:

pythonclass CheckBlockedMiddleware:    def process_response(self, request, response, spider):        if "请输入验证" in response.text or "access denied" in response.text.lower():
            spider.logger.warning(f"触发验证页:{request.url}")
            proxy = request.meta.get("_used_proxy")            if proxy:
                remove_bad_proxy(proxy)
            request.meta.pop("proxy", None)            return request  # 放回调度队列重抓
        return response

这套逻辑配上 Python 爬虫代理 IP,才能让“被拦”变成可恢复事件,而不是默默存一堆垃圾页进数据库。

并发别无脑拉满

Scrapy 默认 CONCURRENT_REQUESTS 不算小,但代理通道有吞吐上限。你开 32 并发,网关只够 8 路稳跑,剩下全是超时。

更稳的配置思路:

pythonCONCURRENT_REQUESTS = 8DOWNLOAD_DELAY = 1.0RANDOMIZE_DOWNLOAD_DELAY = True

Python 爬虫代理 IP 解决的是身份分散,不解决“你发太快”。节奏控制永远在代理前面。

多蜘蛛不同业务要隔离

如果你一个 Scrapy 项目里跑电商比价、新闻采集、SERP 监控,别用同一个出口池。电商页怕关联,新闻页怕限流,SERP 页怕查询过密,业务性质完全不同。

可以按 spider.name 分配不同网关:

pythonGATEWAY_MAP = {    "news_spider": "http://用户:密码@news-gw:端口",    "price_spider": "http://用户:密码@price-gw:端口",    "serp_spider": "http://用户:密码@serp-gw:端口",
}class BizProxyMiddleware:    def process_request(self, request, spider):
        request.meta["proxy"] = GATEWAY_MAP.get(spider.name)

Python 爬虫代理 IP 做到业务隔离,排障时才不会“一个业务被封,全项目陪葬”。

小结

Scrapy 里接代理,重点不是会写 request.meta["proxy"],而是把出口层做成可观测、可切换、可隔离的中间件系统。Python 爬虫代理 IP 放对位置,爬虫项目才像生产系统,不像玩具脚本。


相关标签:代理ip,ip代理,http代理,代理服务器ip,开放代理,文档中心,新闻,动态住宅ip,ip池,socks5代理

微信客服

微信客服

扫码添加客服

QQ 咨询

新用户专享 注册免费送 IP 5000个 高质量 IP 免费领取 立即领取