跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python

Scrapy 框架配置免费代理 IP 及爬虫防封方法

Scrapy 配置免费代理 IP 是爬虫防封的重要手段。三种配置方式:直接在 Request 指定、通过下载中间件随机切换、动态获取代理。重点讲解了代理筛选脚本编写、settings.py 配置(如下载延迟、User-Agent)以及处理异常状态码的重试逻辑。同时提供了使用免费代理的注意事项,包括避免高频请求、优先高匿代理及法律合规建议。

MongoKing发布于 2026/3/28更新于 2026/7/1737 浏览
Scrapy 框架配置免费代理 IP 及爬虫防封方法

在爬虫开发中,IP 封禁是最常见的阻碍之一。Scrapy 作为 Python 生态中最强大的爬虫框架,通过合理配置代理 IP 可以有效规避单 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 等配置,才能最大程度降低被封风险。

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

目录

  1. 一、免费代理 IP 的获取与筛选
  2. 1.1 免费代理 IP 的获取渠道
  3. 1.2 代理有效性筛选
  4. 测试示例
  5. 二、Scrapy 中配置代理 IP 的 3 种方式
  6. 2.1 方式 1:直接在 Request 中指定(单次生效)
  7. 2.2 方式 2:通过下载中间件实现代理池随机切换(推荐)
  8. 步骤 1:编写代理中间件(middlewares.py)
  9. 步骤 2:配置 settings.py
  10. 1. 启用自定义代理中间件
  11. 2. 配置可用的代理列表(替换为你筛选后的代理)
  12. 3. 其他防封配置(重要)
  13. 禁用 Cookie,避免被识别为同一用户
  14. 设置下载延迟,避免请求过快
  15. 随机化下载延迟(1-3 秒)
  16. 设置请求头,模拟浏览器
  17. 重试次数
  18. 重试的状态码
  19. 步骤 3:编写测试爬虫
  20. 2.3 方式 3:动态获取免费代理(进阶)
  21. 三、免费代理 IP 使用避坑指南
  22. 四、完整配置验证
  23. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 龙虾机器人本地部署与配置指南
  • Python IDLE 使用指南:Python 自带集成开发环境入门
  • AI 辅助开发:利用 DeepSeek 构建贪吃蛇游戏
  • 大模型微调核心:数据准备与 3 个实例详解
  • ArrayList 与 LinkedList 性能实测:插入、遍历与删除耗时对比
  • VRChat 跨语言交流工具 VRCT 使用指南
  • Flutter for OpenHarmony 集成 dart_openai 实现 AIGC 功能
  • 如何选择最适合您需求的向量数据库
  • Vue 3 常用编程技巧整理
  • Stable Diffusion WebUI 整合包安装与使用指南
  • Python 音乐推荐系统:Django+Echarts+协同过滤算法
  • 前端实现液态玻璃效果
  • OpenClaw 飞书机器人搭建流程
  • Java GUI 组件详解:下拉菜单与弹出菜单
  • 企业级图像AIGC技术:Seedream 4.0 模型能力与应用场景
  • xsimd 实战指南:从零开始掌握 C++ SIMD 编程
  • 九么 1.0.31:AI 辅助 Python 数据处理实战
  • .NET WebApi 项目必要可配置项详解
  • CISP-PTE 渗透测试工程师备考指南与知识体系解析
  • 主流后量子密码算法 PQC 技术路线解析及展望

相关免费在线工具

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online