当前位置: 首页 > news >正文

Scrapy 框架怎么配置免费代理 IP?爬虫防封实操教程(附配置代码)

在爬虫开发中,IP 封禁是最常见的阻碍之一。Scrapy 作为 Python 生态中最强大的爬虫框架,通过合理配置代理 IP 可以有效规避单 IP 访问频率限制,降低被封风险。今天,手把手教你在 Scrapy 中配置免费代理 IP,包含完整代码实现和避坑指南,所有操作均经过真实环境验证。

一、免费代理 IP 的获取与筛选

在配置代理前,首先要解决 “代理从哪来” 的问题。免费代理 IP 虽然稳定性差,但胜在成本低,适合小规模爬虫场景。

1.1 免费代理 IP 的获取渠道

市面上有很多免费代理 IP 分享平台,我之前的文章有提到过,哲理不再一一赘述,这类平台会定期更新公开的代理资源,涵盖 HTTP/HTTPS 等类型,很多提供API接口获取,能满足基础的爬虫使用需求。

1.2 代理有效性筛选

免费代理的可用率通常不足 10%,必须先筛选出存活的 IP 才能使用。以下是一个简单的代理检测脚本:

import requests import time def check_proxy(proxy): """ 检测代理是否可用 :param proxy: 代理格式 'http://ip:port' :return: True/False """ test_url = "http://httpbin.org/ip" # 验证IP的测试地址 timeout = 5 # 超时时间5秒 try: response = requests.get( test_url, proxies={"http": proxy, "https": proxy}, timeout=timeout ) if response.status_code == 200: print(f"代理可用: {proxy}") return True except Exception as e: # 捕获连接超时、拒绝连接等异常 print(f"代理不可用: {proxy}, 原因: {str(e)[:50]}") return False # 测试示例 if __name__ == "__main__": # 从代理分享平台获取的IP列表 proxy_list = [ "http://112.14.47.6:52024", "http://180.122.151.186:3000", "http://223.241.78.143:8080" ] valid_proxies = [] for proxy in proxy_list: if check_proxy(proxy): valid_proxies.append(proxy) print(f"可用代理列表: {valid_proxies}")

关键说明

  • 测试地址优先选择httpbin.org/ip,可直接返回当前出口 IP,验证代理是否生效
  • 超时时间建议设置为 3-5 秒,过长会降低筛选效率,过短会误判可用代理
  • 免费代理存活时间短,建议每次爬取前重新筛选

二、Scrapy 中配置代理 IP 的 3 种方式

Scrapy 配置代理的核心是修改请求的meta参数或通过下载中间件(Downloader Middleware)实现,以下是 3 种实战方案,从简单到进阶逐步讲解。

2.1 方式 1:直接在 Request 中指定(单次生效)

适合临时测试或少量请求的场景,直接在生成 Request 时添加代理参数:

import scrapy class ProxyTestSpider(scrapy.Spider): name = "proxy_test" allowed_domains = ["httpbin.org"] start_urls = ["http://httpbin.org/ip"] def start_requests(self): # 单个代理示例 proxy = "http://112.14.47.6:52024" for url in self.start_urls: yield scrapy.Request( url=url, callback=self.parse, meta={"proxy": proxy} # 核心配置:添加proxy元数据 ) def parse(self, response): # 打印返回结果,验证出口IP是否为代理IP self.logger.info(f"响应结果: {response.text}")

优点:简单直接,无需额外配置;缺点:无法自动切换代理,复用性差

2.2 方式 2:通过下载中间件实现代理池随机切换(推荐)

这是生产环境中最常用的方案,通过自定义下载中间件,每次请求从代理池中随机选择一个 IP,实现自动切换。

步骤 1:编写代理中间件(middlewares.py)
import random from scrapy import signals class ProxyMiddleware: """自定义代理中间件,实现随机切换代理IP""" def __init__(self, proxy_list): # 初始化代理池 self.proxy_list = proxy_list @classmethod def from_crawler(cls, crawler): # 从配置文件读取代理列表 proxy_list = crawler.settings.getlist("PROXY_LIST") return cls(proxy_list) def process_request(self, request, spider): """在请求发送前添加代理""" if self.proxy_list: # 随机选择一个代理 proxy = random.choice(self.proxy_list) request.meta["proxy"] = proxy spider.logger.info(f"当前使用代理: {proxy}") return None def process_response(self, request, response, spider): """处理响应,若返回异常状态码则更换代理重试""" # 常见的封禁状态码:403/407/503/504 if response.status in [403, 407, 503, 504]: spider.logger.warning(f"代理失效,状态码: {response.status}") # 更换代理重新请求 if self.proxy_list: new_proxy = random.choice(self.proxy_list) request.meta["proxy"] = new_proxy return request.copy() # 重新发起请求 return response def process_exception(self, request, exception, spider): """处理请求异常,更换代理重试""" spider.logger.error(f"请求异常: {exception}") if self.proxy_list: new_proxy = random.choice(self.proxy_list) request.meta["proxy"] = new_proxy return request.copy()
步骤 2:配置 settings.py
# 1. 启用自定义代理中间件 DOWNLOADER_MIDDLEWARES = { # 禁用Scrapy默认的代理中间件(如果有的话) 'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': None, # 启用自定义代理中间件(优先级建议设置为750,在UserAgent中间件之后) 'your_project_name.middlewares.ProxyMiddleware': 750, } # 2. 配置可用的代理列表(替换为你筛选后的代理) PROXY_LIST = [ "http://112.14.47.6:52024", "http://180.122.151.186:3000", "http://223.241.78.143:8080", ] # 3. 其他防封配置(重要) # 禁用Cookie,避免被识别为同一用户 COOKIES_ENABLED = False # 设置下载延迟,避免请求过快 DOWNLOAD_DELAY = 2 # 随机化下载延迟(1-3秒) RANDOMIZE_DOWNLOAD_DELAY = True # 设置请求头,模拟浏览器 DEFAULT_REQUEST_HEADERS = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', } # 重试次数 RETRY_TIMES = 3 # 重试的状态码 RETRY_HTTP_CODES = [403, 407, 500, 502, 503, 504]
步骤 3:编写测试爬虫
import scrapy class ProxyPoolSpider(scrapy.Spider): name = "proxy_pool" allowed_domains = ["httpbin.org"] start_urls = ["http://httpbin.org/ip"] def parse(self, response): self.logger.info(f"出口IP: {response.text}") # 可以继续请求其他链接,验证代理自动切换 yield scrapy.Request( url="http://httpbin.org/get", callback=self.parse_get ) def parse_get(self, response): self.logger.info(f"GET请求响应: {response.text[:200]}")

2.3 方式 3:动态获取免费代理(进阶)

免费代理列表需要定期更新,手动维护效率低,可通过爬虫自动抓取代理分享平台的 IP,实时更新代理池。

以下是简化版的动态代理获取中间件(核心逻辑):

import random import requests from scrapy import signals from lxml import etree class DynamicProxyMiddleware: """动态获取免费代理的中间件""" def __init__(self): self.proxy_list = [] # 初始化时抓取一次代理 self.refresh_proxy_list() def refresh_proxy_list(self): """从代理分享平台抓取并筛选可用代理""" # 从代理分享平台抓取高匿代理,如果提供免费接口的可以直接获取更方便 url = "https://www.66daili.com/get-ip/" headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36' } try: response = requests.get(url, headers=headers, timeout=10) html = etree.HTML(response.text) # 解析代理IP和端口 ip_list = html.xpath('//tr/td[2]/text()') port_list = html.xpath('//tr/td[3]/text()') # 拼接代理并筛选 temp_proxies = [f"http://{ip}:{port}" for ip, port in zip(ip_list, port_list)] self.proxy_list = [p for p in temp_proxies if self.check_proxy(p)] print(f"更新代理池,可用代理数量: {len(self.proxy_list)}") except Exception as e: print(f"获取代理失败: {e}") def check_proxy(self, proxy): """检测代理有效性""" test_url = "http://httpbin.org/ip" try: resp = requests.get(test_url, proxies={"http": proxy}, timeout=3) return resp.status_code == 200 except: return False def process_request(self, request, spider): """每次请求前检查代理池,为空则刷新""" if not self.proxy_list: self.refresh_proxy_list() if self.proxy_list: proxy = random.choice(self.proxy_list) request.meta["proxy"] = proxy return None

三、免费代理 IP 使用避坑指南(真实踩坑经验)

  1. 不要过度依赖免费代理:免费代理可用率低(通常 < 10%)、存活时间短(分钟级),仅适合小规模、低频率爬虫,大规模爬取建议使用付费代理池或自建代理。
  2. 避免请求频率过高:即使使用代理,短时间内对同一网站发起大量请求仍会被封,务必设置DOWNLOAD_DELAY(建议 2-5 秒),并开启RANDOMIZE_DOWNLOAD_DELAY
  3. 优先选择高匿代理:免费代理分透明、匿名、高匿三种,只有高匿代理能完全隐藏真实 IP,透明代理会暴露真实 IP,等于没用。
  4. 处理代理失效重试:一定要在中间件中处理 403/503 等状态码和连接异常,自动更换代理重试,否则爬虫会频繁中断。
  5. 不要爬取敏感网站:部分网站对爬虫监控严格,即使使用代理也可能被封,且可能涉及法律风险,爬取前需确认网站 robots 协议和相关法规。

四、完整配置验证

2026-02-25 10:00:00 [proxy_pool] INFO: 当前使用代理: http://112.14.47.6:52024 2026-02-25 10:00:02 [proxy_pool] INFO: 出口IP: {"origin":"112.14.47.6"} 2026-02-25 10:00:04 [proxy_pool] INFO: 当前使用代理: http://180.122.151.186:3000 2026-02-25 10:00:06 [proxy_pool] INFO: GET请求响应: {"args":{},"headers":{"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8","Accept-Language":"zh-CN,zh;q=0.9,en;q=0.8","Host":"httpbin.org","User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36","X-Amzn-Trace-Id":"Root=1-67e3b8c6-1234567890abcdef12345678"},"origin":"180.122.151.186","url":"http://httpbin.org/get"}

若日志中显示的origin为代理 IP,说明配置成功。

总结

  1. Scrapy 配置免费代理的核心是通过meta["proxy"]参数为请求添加代理,推荐使用下载中间件实现代理池随机切换,兼顾灵活性和易用性;
  2. 免费代理必须先筛选再使用,且要处理代理失效后的重试逻辑,否则会导致爬虫效率极低;
  3. 代理只是防封手段之一,需配合下载延迟、随机 UA、禁用 Cookie 等配置,才能最大程度降低被封风险。

免费代理适合学习和小规模爬取场景,若需稳定的爬虫服务,建议结合付费代理池、分布式爬虫等方案,进一步提升爬虫的稳定性和效率。

http://www.jsqmd.com/news/412446/

相关文章:

  • 11.4 用户反馈闭环:从采集到迭代的持续优化策略
  • Django Admin 管理工具
  • 【UI自动化测试】6_PO模式 _数据驱动
  • Grafana 接入 SSO 配置指南
  • 华为晟腾计算芯片 —— AI国产化 —— Ascend / pytorch —— 支持NPU的pytorch下载地址
  • ArgoCD 接入 SSO 配置指南
  • 【每日一题】LeetCode 1356. 根据数字二进制下 1 的数目排序
  • HTML 布局
  • 信用卡债务协商最佳解决方案,信用卡债务协商真的能帮我摆脱困境吗? - 代码非世界
  • 文件夹监控文件变动通知器
  • 【eclipse 升级】
  • 像素蛋糕专用
  • 信用卡逾期后,如何才能成功申请60期分期?这样协商还款,压力瞬间减半 - 代码非世界
  • 大气电场监测仪:实时测量大气中的电场强度变化
  • 信用卡债务协商:探寻最佳解决方案,信用卡债务协商的最佳解决方案到底是什么? - 代码非世界
  • 11.3 监控与可观测性:指标体系、日志追踪、drift检测
  • LuxTTS语音克隆
  • 青木川古镇酒店排名哪家好?2026最新榜单,青云客栈稳居首选! - 一个呆呆
  • 11.2 模型路由与网关:多模型调度、流量切分、故障转移
  • 青木川酒店排名哪家好?2026最新榜单,青云客栈稳居首选! - 一个呆呆
  • 11.1 AI工程五步构建法:增强上下文、护栏、路由、缓存、智能体
  • 小白也能轻松做GEO优化了,立省万元
  • 每天登录10个自媒体后台太累了试试这个一键发布工具
  • 10.3 服务优化:连续批处理、动态批处理、负载均衡实战
  • 10.4 AI加速器选型:GPU、TPU、NPU架构与算力对比
  • 软件专业毕设中HTML技术与Python技术如何结合用
  • LeetCode 1356.根据数字二进制下 1 的数目排序:自定义排序模拟
  • django基于python文化旅游信息公开管理平台的设计与实现
  • 信用卡与贷款协商分期 委托律师处理的全流程实操指南,信用卡和贷款协商分期,到底该怎么委托律师处理? - 代码非世界
  • 最高补 1000 万!2026 福建省级 AI 项目申报全攻略,AI企业必看的申报要点与实操指南