首页
/ Scrapy 设置系统详解:六层优先级栈、特殊设置机制与内置设置项全参考

Scrapy 设置系统详解:六层优先级栈、特殊设置机制与内置设置项全参考

2026-09-06 12:58:38作者:农烁颖Land

Scrapy 的 Settings(设置系统)是整个框架的配置中枢:它以带优先级的键值命名空间,统一驱动下载器、中间件、管道、扩展与 Spider 本身的行为。本文基于官方文档 docs/topics/settings.rst 与源码 scrapy/settings/__init__.pyscrapy/settings/default_settings.py 展开,讲清设置的指定方式、六层优先级覆盖规则、组件优先级字典的合并机制、预爬虫/Reactor/日志三类特殊设置的约束,并按功能域系统梳理全部内置设置项及其默认值,帮助你在实际项目中写出正确且可复制的配置。

1. Settings 是什么:带优先级的全局键值命名空间

Scrapy 的设置允许你定制所有 Scrapy 组件(包括核心、扩展、管道和 Spider 本身)的行为。其基础设施是一个全局的键值映射命名空间,代码从其中拉取配置值;设置可以通过不同机制填入,每种机制具有不同的优先级(precedence)。设置同时还是选择当前活动 Scrapy 项目(当你有多个项目时)的机制。

从源码看,这个命名空间由 BaseSettings 类 实现,它是一个 MutableMapping(行为类似字典),但与普通字典有两点关键区别:

  • 每个 (key, value) 对都附带存储一个优先级,查询时返回优先级最高的值;
  • 支持 freeze() 冻结为不可变对象,防止 Crawler 应用设置后仍被修改。

每个键的值封装在 SettingsAttribute 中,其 set() 方法的规则是:只有当新值优先级 >= 当前优先级时才覆盖(见 SettingsAttribute)。

六个命名优先级的数值定义在 SETTINGS_PRIORITIES 中:

SETTINGS_PRIORITIES = {
    "default": 0,     # 全局默认设置
    "command": 10,    # 命令级默认设置
    "addon": 15,      # Add-on 设置
    "project": 20,    # 项目设置
    "spider": 30,    # Spider 设置
    "cmdline": 40,   # 命令行设置
}

两个工程约束值得注意:

  • 设置值必须可以被 pickle 序列化(Scrapy 会在需要时序列化请求与状态);
  • 当设置引用一个需要 Scrapy 导入的可调用对象(类或函数)时,可以用导入路径字符串(如 "mybot.pipelines.validate.ValidateMyItem")或对象本身(如 ValidateMyItem)两种等价方式指定;不支持传入非可调用对象。
from mybot.pipelines.validate import ValidateMyItem

ITEM_PIPELINES = {
    # 直接传类对象...
    ValidateMyItem: 300,
    # ...等价于传导入路径字符串
    "mybot.pipelines.validate.ValidateMyItem": 300,
}

2. 指定设置模块:SCRAPY_SETTINGS_MODULE

使用 Scrapy 时必须告诉它使用哪份设置,方式是环境变量 SCRAPY_SETTINGS_MODULE。其取值应为 Python 路径语法,例如 myproject.settings,且该设置模块必须位于 Python 导入搜索路径(import search path)上。

项目级设置的加载入口是 scrapy.utils.project.get_project_settingsscrapy/utils/project.py):

def get_project_settings() -> Settings:
    """返回当前项目的 Settings 对象(project 优先级)。
    更高优先级的来源(如 spider 设置)会在爬取启动时应用。"""
    if ENVVAR not in os.environ:
        project = os.environ.get("SCRAPY_PROJECT", "default")
        init_env(project)

    settings = Settings()
    settings_module_path = os.environ.get(ENVVAR)
    if settings_module_path:
        settings.setmodule(settings_module_path, priority="project")

其中 setmodule 的实现(setmodule)只采集模块中全大写声明的变量,因此 settings.py 中的小写变量(普通函数、导入名)不会成为设置项。get_project_settings 的典型用途是在脚本方式(run-from-script)运行 Scrapy 时,把项目设置传给 AsyncCrawlerProcess / CrawlerProcess

3. 六层优先级栈:设置如何被填充与覆盖

设置可经由不同机制填充,优先级从高到低依次为:

层级 来源 对应优先级名(数值)
1 命令行设置 cmdline(40)
2 Spider 设置 spider(30)
3 项目设置 project(20)
4 Add-on 设置 addon(15)
5 命令级默认设置 command(10)
6 全局默认设置 default(0)

3.1 命令行设置(最高优先级)

使用 -s(或 --set)选项显式覆盖一个或多个设置,可压过其他所有来源:

scrapy crawl myspider -s LOG_LEVEL=INFO -s LOG_FILE=scrapy.log

由于命令行传入的都是字符串,读取侧需要配合 getbool/getint 等类型转换方法(见第 5 节)。

3.2 Spider 设置

Spider 可以定义自己的设置,优先于并覆盖项目设置。共有三种方式:

方式一:custom_settings 类属性

import scrapy


class MySpider(scrapy.Spider):
    name = "myspider"

    custom_settings = {
        "SOME_SETTING": "some value",
    }

方式二:实现 update_settings 类方法(Scrapy 2.11 起支持)。官方文档认为这通常更好,且其中的设置应显式使用 "spider" 优先级:

import scrapy


class MySpider(scrapy.Spider):
    name = "myspider"

    @classmethod
    def update_settings(cls, settings):
        super().update_settings(settings)
        settings.set("SOME_SETTING", "some value", priority="spider")

从源码看,update_settingsSpider 基类的类方法(scrapy/spiders/init.py),在 Crawler 创建 Spider 实例之前被调用(scrapy/crawler.py 中执行 self.spidercls.update_settings(self.settings))。

方式三:在 from_crawler 中动态修改(2.11 起),例如基于 Spider 启动参数 或自定义逻辑:

import scrapy


class MySpider(scrapy.Spider):
    name = "myspider"

    @classmethod
    def from_crawler(cls, crawler, *args, **kwargs):
        spider = super().from_crawler(crawler, *args, **kwargs)
        if "some_argument" in kwargs:
            spider.settings.set(
                "SOME_SETTING", kwargs["some_argument"], priority="spider"
            )
        return spider

注意:预爬虫设置(Pre-crawler settings)不能按 Spider 定义;Reactor 设置与日志设置在同进程运行多个 Spider 时受限制(见第 6 节)。

3.3 项目设置

Scrapy 项目包含一个设置模块,通常是名为 settings.py 的文件,绝大多数对全部 Spider 生效的设置都应写在这里。startproject 命令会基于模板 settings.py.tmpl 生成该文件,其中一些设置被设定为与全局默认不同的值。

3.4 Add-on 设置

Add-on(见 docs/topics/addons.rst)可以修改设置,应尽可能使用 "addon" 优先级。从源码看,框架在启用 Add-on 后调用其 update_settings 方法(scrapy/addons.py)。

3.5 命令级默认设置

每个 Scrapy 命令类可以有自己的 default_settings 属性,其中的默认值覆盖全局默认设置(如 crawl 命令的 command 优先级值)。

3.6 全局默认设置

scrapy.settings.default_settings 模块(对应 scrapy/settings/default_settings.py)为各内置设置定义全局默认值。Settings 类在实例化时即以 "default" 优先级加载该模块(Settings.init),并把默认值中的字典提升为 BaseSettings 实例以支持逐键优先级。

关于"默认值"的文档约定:内置设置参考(第 7 节)标注的是存在默认值时的默认值;若 startproject 生成的 settings.py 也设置了某值,则以该生成值为"默认",而 default_settings 中的值标注为 fallback(后备值)。典型例子:CONCURRENT_REQUESTS_PER_DOMAIN 默认为 1、fallback 为 8DOWNLOAD_DELAY 默认为 1、fallback 为 0ROBOTSTXT_OBEY 默认为 True、fallback 为 False(历史原因导致默认是 False,但 startproject 生成的 settings.py 中已启用它)。

4. 组件优先级字典:中间件/管道/扩展的统一编排结构

**组件优先级字典(component priority dictionary)**是一个字典:键是组件(可以是类对象或导入路径字符串),值是组件优先级(intNone):

{
    "path.to.ComponentA": None,
    ComponentB: 100,
}

三条核心规则:

  1. 优先级数字越小越靠前(优先级 1 的组件在优先级 2 之前)。但"在前"的具体含义取决于对应设置——例如在 DOWNLOADER_MIDDLEWARES 中,靠前的组件其 process_request 方法先于靠后组件执行,而其 process_response 方法则后于靠后组件执行;
  2. 优先级为 None 表示禁用该组件
  3. 某些组件优先级字典会与内置的 _BASE 值合并。例如 DOWNLOADER_MIDDLEWARES 会与 DOWNLOADER_MIDDLEWARES_BASE 合并,此时 None 正好用来在常规设置中禁用 base 里的组件:
DOWNLOADER_MIDDLEWARES = {
    "scrapy.downloadermiddlewares.offsite.OffsiteMiddleware": None,
}

合并逻辑实现于 get_component_priority_dict_with_base:先以 _BASE 值打底,再用设置值覆盖(键经 load_object 解析为导入路径做去重,防止同一组件以"字符串 + 类对象"两种形式重复定义),最后丢弃所有值为 None 的项——这正是"用 None 禁用组件"能生效的底层原因。

官方警告:组件优先级字典是普通 dict,切勿把同一组件定义两次(例如同时用不同的导入路径字符串,或路径字符串与类对象各写一份)。源码中对此已有检测,会记录警告"Setting {name} contains multiple keys that refer to the same object ... Only the last one will be kept"(源码)。

5. 如何读取设置:从字典访问到类型转换 API

在 Spider 中,设置通过 self.settings 访问:

class MySpider(scrapy.Spider):
    name = "myspider"
    start_urls = ["http://example.com"]

    def parse(self, response):
        print(f"Existing settings: {self.settings.attributes.keys()}")

注意:settings 属性是在基类 Spider 中初始化之后才设置的。若想在初始化之前(例如 Spider 的 __init__() 中)使用设置,需要重写 from_crawler 方法。其他组件(扩展、中间件、管道等)也有各自的设置访问途径(参见组件文档)。

settings 对象可以像 dict 一样使用(如 settings["LOG_ENABLED"]),但为了支持以字符串形式从命令行传入的非字符串值,官方建议使用 Settings API 提供的方法。从源码看(scrapy/settings/init.py),各方法的语义如下:

方法 行为
get(name, default) 原样取值,不改变类型
getbool(name, default) 1/'1'/True/'True' 返回 True0/'0'/False/'False'/None 返回 False。环境变量设置为 '0' 时即返回 False
getint(name, default) / getfloat(name, default) 转为 int / float
getlist(name, default) 若原值是字符串则按 , 切分;如环境变量 'one,two' 得到 ['one', 'two']
getdict(name, default) 若原值是字符串则按 JSON 解析为字典
getdictorlist(name, default) 支持 dict 或 list;字符串先按 JSON 解析,失败则回退为逗号切分列表

这些类型转换方法正是命令行 -s KEY=value 全字符串值能被正确消费的底层机制。

6. 特殊设置:预爬虫设置、Reactor 设置与日志设置

以下三类设置的行为与其他设置不同,配置时必须了解其约束边界。

6.1 预爬虫设置(Pre-crawler settings)

预爬虫设置是Crawler 对象创建之前就被使用的设置,因此不能由 Spider 设置。包括:

  • ADDONS
  • COMMANDS_MODULE
  • FORCE_CRAWLER_PROCESS
  • SPIDER_LOADER_CLASS 及对应 Spider 加载器类使用的设置,如默认加载器的 SPIDER_MODULESSPIDER_LOADER_WARN_ONLY
  • TWISTED_REACTOR_ENABLED

其中 ADDONS 是特例:它可以由 Spider 设置,但通过这种方式启用的 add-on 的 update_pre_crawler_settings() 方法不会被调用。TWISTED_REACTOR 在运行需要 CrawlerProcess 的命令时同样充当预爬虫设置,因为其项目级值决定了使用哪个爬虫进程类。

6.2 Reactor 设置

Reactor 设置与 Twisted reactor 绑定。由于一个进程只能有一个 reactor,同进程运行多个 Spider 时这些设置不能按 Spider 取不同值。

在 reactor 安装时使用的设置

  • ASYNCIO_EVENT_LOOP(使用 AsyncCrawlerProcess 时不能按 Spider 设置,见下)
  • TWISTED_REACTOR(使用 AsyncCrawlerProcess 时被忽略,见下)

它们可以由 Spider 设置,但只有第一个运行的 Spider 的值生效(reactor 在安装时才读取);若后来的 Spider 要求不同的 reactor 或事件循环,将抛出异常。使用 CrawlerRunner / AsyncCrawlerRunner 时,reactor 必须提前装好,这些设置只用于校验已安装的 reactor/事件循环与设置一致。

在 reactor 启动时应用的设置

  • TWISTED_DNS_RESOLVER 及其对应组件的设置(默认组件对应 DNSCACHE_ENABLEDDNSCACHE_SIZEDNS_TIMEOUT
  • REACTOR_THREADPOOL_MAXSIZE

它们从 CrawlerProcess / AsyncCrawlerProcess 对象的设置中读取,因此从 Spider 或 add-on 设置无效;使用 CrawlerRunner / AsyncCrawlerRunner(它们不启动 reactor)时被完全忽略。

AsyncCrawlerProcess 有额外限制:其实例化时即安装 twisted.internet.asyncioreactor.AsyncioSelectorReactor忽略 TWISTED_REACTOR 的取值,并使用传入 AsyncCrawlerProcess.__init__()ASYNCIO_EVENT_LOOP 值;之后(例如在 Spider 级设置中)再提供不同的 TWISTED_REACTORASYNCIO_EVENT_LOOP 会抛出异常。除 ASYNCIO_EVENT_LOOP 外,这些设置都只在 TWISTED_REACTOR_ENABLEDTrue(即使用 Twisted reactor)时生效。

6.3 日志设置

日志设置配置由 scrapy.utils.log.configure_logging 安装的全局根日志处理器。它们可以由 Spider 定义,但由于一个进程只有一个活动的根日志处理器,同进程多 Spider 时不能按 Spider 取不同值。共 9 项:

LOG_DATEFORMATLOG_ENABLEDLOG_ENCODINGLOG_FILELOG_FILE_APPENDLOG_FORMATLOG_LEVELLOG_SHORT_NAMESLOG_STDOUT

7. 内置设置项全参考(按功能域分组)

官方参考按字母序列出全部内置设置及其默认值与作用域(Scope)。Scope 表示该设置被哪个组件使用(通常是某个扩展、中间件或管道),意味着该组件必须被启用,设置才会生效。下表完整继承参考文档的全部设置项,按功能域重新组织以便查阅;标注"fallback"的项表示 startproject 生成的 settings.py 中的值为默认值、default_settings 中的值为后备值。

7.1 项目、爬虫进程与并发

设置项 默认值 说明
ADDONS {} 启用 add-on 的字典(导入路径 → 优先级)。预爬虫设置,有特例(见 6.1)
BOT_NAME <project name>(fallback: 'scrapybot' 本项目 bot 名称,也用于日志。startproject 时自动填充
CONCURRENT_REQUESTS 16 下载器全局最大并发请求数,0 表示不限制
CONCURRENT_REQUESTS_PER_DOMAIN 1(fallback: 8 单个域名的最大并发请求数。可用 DOWNLOAD_SLOTS 按域名覆盖;与自动限流 AUTOTHROTTLE_TARGET_CONCURRENCY 相关
CONCURRENT_ITEMS 100 每个响应在物品管道中并行处理的最大物品数
NEWSPIDER_MODULE <project name>.spiders(fallback: "" genspider 创建新 Spider 的目标模块,如 NEWSPIDER_MODULE = "mybot.spiders_dev"
SPIDER_MODULES ["<project name>.spiders"](fallback: [] 查找 Spider 的模块列表,如 ["mybot.spiders_prod", "mybot.spiders_dev"]预爬虫设置
SPIDER_LOADER_CLASS 'scrapy.spiderloader.SpiderLoader' Spider 加载器类,须实现 SpiderLoader 接口。预爬虫设置
SPIDER_LOADER_WARN_ONLY False 导入 Spider 时遇到 ImportError/SyntaxError 是否降级为警告。预爬虫设置
FORCE_CRAWLER_PROCESS False 需要 CrawlerProcess 的命令在 TWISTED_REACTOR_ENABLED=True 时,是否在 AsyncCrawlerProcessCrawlerProcess 间按 TWISTED_REACTOR 值自动选择(False)还是始终用 CrawlerProcessTrue)。若想在 Spider 级设置中把 TWISTED_REACTOR 设为非默认值,需将其设为 True预爬虫设置
DEFAULT_ITEM_CLASS 'scrapy.item.Item' Scrapy shell 中实例化物品使用的默认类
DEFAULT_REQUEST_HEADERS {"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en"} Scrapy HTTP 请求的默认请求头,由 DefaultHeadersMiddleware 填充。注意:Cookie 头中的 cookie 不受 cookie 中间件管理,应使用 Request.cookies;此处定义的 Referer 只对 RefererMiddleware 未设置的请求(如 start requests)生效,想让每个请求都带上可把 REFERRER_POLICY 设为 "no-referrer"
USER_AGENT "Scrapy/VERSION (+https://scrapy.org)" 默认 User-Agent。官方建议设为可识别你自己的值并附带联系方式,如 "MyProject (+https://example.com/bot)",便于站点方联系你调整爬虫而不是直接封禁
EDITOR Unix 下 vi,Windows 下 IDLE edit 命令使用的编辑器;EDITOR 环境变量优先于该设置
TEMPLATES_DIR scrapy 模块内的 templates 目录 startproject / genspider 查找模板的目录。项目名不得与 project 子目录中的自定义文件/目录名冲突
JOBDIR None 暂停/恢复爬取时保存爬取状态的目录
SCRAPER_SLOT_MAX_ACTIVE_SIZE 5_000_000 正在处理的响应数据总量软上限(字节);超过后 Scrapy 不再处理新请求
WARN_ON_GENERATOR_RETURN_VALUE True 启用时对生成器回调(如 parse)中出现带非 None 返回值的 return 语句给出警告,帮助发现 Spider 开发错误;动态修改回调源码、跳过 AST 解析或提升自动重载开发环境性能时可关闭

7.2 下载、超时与限速

设置项 默认值 说明
DOWNLOAD_DELAY 1(fallback: 0 同一域名两次连续请求之间的最小等待秒数,支持小数,用于限制爬取速度。受 RANDOMIZE_DOWNLOAD_DELAY 影响。注意:它可能把单域有效并发压到低于 CONCURRENT_REQUESTS_PER_DOMAIN——若某域响应时间低于 DOWNLOAD_DELAY,该域有效并发即为 1。调优时建议先把 CONCURRENT_REQUESTS_PER_DOMAIN 降到 1,再逐步增大 DOWNLOAD_DELAY。可用 DOWNLOAD_SLOTS 按域覆盖
RANDOMIZE_DOWNLOAD_DELAY True 启用后,从同一网站抓取时等待 0.5 × DOWNLOAD_DELAY1.5 × DOWNLOAD_DELAY 之间的随机时间,降低被请求间隔统计检测发现(进而被封)的概率;随机化策略与 wget 的 --random-wait 相同。DOWNLOAD_DELAY 为 0 时无效。可用 DOWNLOAD_SLOTS 按域覆盖
DOWNLOAD_SLOTS {} 按槽(域名)定义并发/延迟参数。请求按其 URL 域名分配到槽;也可通过 download_slot 请求 meta 键显式指定槽名(该键随后保留槽名,且重定向时沿用原请求的槽,即使目标域名不同)
DOWNLOAD_TIMEOUT 180 下载器等待超时的秒数。可经请求 meta 键 download_timeout 按请求覆盖
DOWNLOAD_MAXSIZE 1073741824(1 GiB) 允许的最大响应体(字节),压缩前后都适用;超过则中止并忽略响应,解压后超限也会中止。0 表示禁用。可经 meta 键 download_maxsize 按请求覆盖
DOWNLOAD_WARNSIZE 33554432(32 MiB) 响应大小(压缩前后)超过该值时记录警告日志。0 表示禁用。可经 meta 键 download_warnsize 按请求覆盖
DOWNLOAD_FAIL_ON_DATALOSS True 声明的 Content-Length 与实际内容不符、或分块响应未正确结束时:True 抛出 ResponseDataLossErrorFalse 则放行并在 response.flags 中加入 dataloss。可经 meta 键 download_fail_on_dataloss 按请求设为 False。若 RETRY_ENABLEDTrue 且本设为 True,数据丢失错误会按常规被重试。注意 H2DownloadHandler(HTTP/2)忽略此设置——数据丢失可能损坏整条连接,总是对该连接上每个请求抛出 ResponseFailed([InvalidBodyLengthError])
DOWNLOAD_VERIFY_CERTIFICATES False HTTPS 下载器是否验证服务器 TLS 证书,验证失败则中止请求
DOWNLOAD_BIND_ADDRESS None 下载器连接的默认本地出站地址,可以是主机字符串(端口自动选择)或 (host, port) 元组。内置 HTTP 下载器默认使用它;可经 bindaddress 请求 meta 键按请求覆盖。指定端口不被 HttpxDownloadHandler 支持
DOWNLOADER 'scrapy.core.downloader.Downloader' 使用的下载器类
DOWNLOADER_STATS True 是否启用下载器统计收集
HTTP2_MAX_FRAME_SIZE 16384 允许服务器发送的最大 HTTP/2 帧大小(字节),介于 1638416777215 之间;服务器发送更大帧时连接失败。DOWNLOAD_MAXSIZE/DOWNLOAD_WARNSIZE 按每帧检查一次,值调高会增大响应超限后才被发现的窗口。HttpxDownloadHandler 忽略此设置(httpx 不允许配置帧大小)

DOWNLOAD_SLOTS 示例:

DOWNLOAD_SLOTS = {
    "quotes.toscrape.com": {"concurrency": 1, "delay": 2, "randomize_delay": False},
    "books.toscrape.com": {"delay": 3, "randomize_delay": False},
}

未列出的域名槽使用默认值:DOWNLOAD_DELAYdelayCONCURRENT_REQUESTS_PER_DOMAINconcurrencyRANDOMIZE_DOWNLOAD_DELAYrandomize_delay

DOWNLOAD_DELAY 示例(每 10 秒最多发 4 个请求):

DOWNLOAD_DELAY = 2.5

DOWNLOAD_BIND_ADDRESS 示例:

# 绑定到该本地地址
DOWNLOAD_BIND_ADDRESS = "127.0.0.2"

# 绑定到该本地地址和端口
DOWNLOAD_BIND_ADDRESS = ("127.0.0.2", 5000)

7.3 下载处理器与 TLS 安全

设置项 默认值 说明
DOWNLOAD_HANDLERS {} 项目启用的下载处理器字典(URI scheme → 处理器类)。可用 {"ftp": None} 禁用内置 FTP 处理器(不替换)
DOWNLOAD_HANDLERS_BASE 见下 默认启用的下载处理器。不应修改,改 DOWNLOAD_HANDLERS
DOWNLOADER_CLIENT_TLS_CIPHERS 'DEFAULT' 定制 HTTPS 下载器的 TLS 密码套件,取 OpenSSL cipher list 格式字符串,如 'DEFAULT:!DH'(弱 DH 参数站点)或启用 DEFAULT 之外的特定套件。设为 None 使用底层 TLS 实现的默认套件(2.17 起支持)。处理需由下载处理器实现,第三方处理器不保证支持
DOWNLOAD_TLS_MIN_VERSION / DOWNLOAD_TLS_MAX_VERSION None(2.17 起新增) 允许 Scrapy 使用的 TLS 协议版本下限/上限。取值 None 不影响版本选择,或为 'TLSv1.0'/'TLSv1.1'/'TLSv1.2'/'TLSv1.3'。实际允许范围取决于 TLS 实现默认值与这两个设置的组合;可以重新启用"支持但被默认禁用"的版本,但无法启用实现本身不支持的版本(许多现代环境中低于 1.2 的版本不支持)。同样依赖下载处理器实现
DOWNLOADER_CLIENT_TLS_VERBOSE_LOGGING False 设为 True 后,HTTPS 连接建立时记录 TLS 连接参数的 DEBUG 级消息;内容取决于下载处理器与 TLS 库版本
FTP_PASSIVE_MODE True 建立 FTP 传输时是否使用被动模式(除非请求 meta 含 "ftp_passive" 键)
FTP_PASSWORD "guest" 请求 meta 无 "ftp_password" 时使用的 FTP 密码。参照 RFC 1635:匿名 FTP 常用 "guest" 或邮箱地址,但部分服务器明确要求邮箱且不允许 "guest" 登录
FTP_USER "anonymous" 请求 meta 无 "ftp_user" 时使用的 FTP 用户名

DOWNLOAD_HANDLERS_BASE 的默认值随 TWISTED_REACTOR_ENABLED 而变:

# TWISTED_REACTOR_ENABLED 为 True 时
{
    "data": "scrapy.core.downloader.handlers.datauri.DataURIDownloadHandler",
    "file": "scrapy.core.downloader.handlers.file.FileDownloadHandler",
    "http": "scrapy.core.downloader.handlers.http11.HTTP11DownloadHandler",
    "https": "scrapy.core.downloader.handlers.http11.HTTP11DownloadHandler",
    "s3": "scrapy.core.downloader.handlers.s3.S3DownloadHandler",
    "ftp": "scrapy.core.downloader.handlers.ftp.FTPDownloadHandler",
}

# TWISTED_REACTOR_ENABLED 为 False 时
{
    "data": "scrapy.core.downloader.handlers.datauri.DataURIDownloadHandler",
    "file": "scrapy.core.downloader.handlers.file.FileDownloadHandler",
    "http": "scrapy.core.downloader.handlers._httpx.HttpxDownloadHandler",
    "https": "scrapy.core.downloader.handlers._httpx.HttpxDownloadHandler",
    "s3": "scrapy.core.downloader.handlers.s3.S3DownloadHandler",
    "ftp": None,
}

7.4 DNS 与 Reactor

设置项 默认值 说明
TWISTED_REACTOR_ENABLED True(2.15 起新增) 是否安装并使用 Twisted reactor。True 为传统模式;False 时 Scrapy 直接使用 asyncio 事件循环、不装 reactor,依赖 reactor 的功能不可用,但不受"同一进程不能二次启动 reactor"等限制。该模式目前仍是实验性的,不适合生产,第三方代码也可能不支持。预爬虫设置
TWISTED_REACTOR "twisted.internet.asyncioreactor.AsyncioSelectorReactor" 指定 reactor 的导入路径。若尚未安装 reactor(如通过 scrapy CLI 或 CrawlerProcess/AsyncCrawlerProcess 运行时),Scrapy 会安装它。使用 CrawlerRunner/AsyncCrawlerRunner 时需自行用 scrapy.utils.reactor.install_reactor 安装;已安装的 reactor 与本设置不匹配会抛异常,因此项目文件或第三方库中顶层 from twisted.internet import reactor 会触发该异常——应在方法内部延迟导入。设为 None 时使用已安装 reactor 或 Twisted 为当前平台的默认 reactor(2.13 起默认值从 None 改为 asyncio 选择器 reactor)。Reactor 设置
ASYNCIO_EVENT_LOOP None asyncio 事件循环类的导入路径,用于 asyncio reactor 或无 reactor 运行模式;None 用默认事件循环。事件循环类必须继承 asyncio.AbstractEventLoop。使用非默认事件循环时 Scrapy 会调用 asyncio.set_event_loop 将其设为当前 OS 线程的当前循环。Reactor 设置
TWISTED_DNS_RESOLVER 'scrapy.resolver.CachingThreadedResolver' Twisted 用于解析 DNS 的类。默认 CachingThreadedResolver 支持 DNS_TIMEOUT 超时但仅支持 IPv4;替代的 scrapy.resolver.CachingHostnameResolver 支持 IPv4/IPv6 但不读 DNS_TIMEOUTTWISTED_REACTOR_ENABLED=False 时无效。Reactor 设置
DNSCACHE_ENABLED True 是否启用 DNS 内存缓存。仅 CachingThreadedResolverCachingHostnameResolver 使用;无 reactor 模式下无效,换用其他解析器时也可能无效。Reactor 设置
DNSCACHE_SIZE 10000 DNS 内存缓存大小。Reactor 设置
DNS_TIMEOUT 60 DNS 查询处理超时(秒,支持浮点)。计时从查询进入 reactor 线程池时开始,而非发出时——线程池饱和时查询可能在发出前就超时,此时增大 REACTOR_THREADPOOL_MAXSIZE 比增大本设置更有效。仅 CachingThreadedResolver 使用。Reactor 设置
REACTOR_THREADPOOL_MAXSIZE 10 Twisted reactor 线程池上限。这是 DNS 解析器、BlockingFeedStorage、S3FilesStore 等组件共用的多用途线程池;阻塞 IO 不足导致问题时调大它。Reactor 设置

7.5 去重与调度器

设置项 默认值 说明
DUPEFILTER_CLASS 'scrapy.dupefilters.RFPDupeFilter' 检测并过滤重复请求的类。默认 RFPDupeFilter 基于 REQUEST_FINGERPRINTER_CLASS 过滤。改为自定义子类(重写 __init__ 换用不同指纹器)即可定制去重逻辑;设为 'scrapy.dupefilters.BaseDupeFilter' 可完全禁用去重(可能引发爬取死循环,通常建议对特定请求设 dont_filter=True
DUPEFILTER_DEBUG False RFPDupeFilter 默认只记录第一个重复请求;设为 True 记录所有重复请求
SCHEDULER scrapy.core.scheduler.Scheduler 使用的调度器类
SCHEDULER_DEBUG False 设为 True 记录调度器调试信息(目前包括:请求无法序列化到磁盘时仅记录一次),scheduler/unserializable 统计跟踪发生次数
SCHEDULER_DISK_QUEUE 'scrapy.squeues.PickleLifoDiskQueue' 调度器使用的磁盘队列类型,另有 PickleFifoDiskQueueMarshalFifoDiskQueueMarshalLifoDiskQueue
SCHEDULER_MEMORY_QUEUE 'scrapy.squeues.LifoMemoryQueue' 调度器使用的内存队列类型,另有 FifoMemoryQueue
SCHEDULER_PRIORITY_QUEUE scrapy.pqueues.DownloaderAwarePriorityQueue 调度器使用的优先级队列类型,另有 ScrapyPriorityQueue。并行抓取大量不同域名时,DownloaderAwarePriorityQueue 表现更好
SCHEDULER_START_DISK_QUEUE 'scrapy.squeues.PickleFifoDiskQueue' 调度器为 start requests 使用的磁盘队列(与 JOBDIR 相关)。设为 None"" 可完全禁用独立队列,让 start requests 与其他请求共用队列——此时 start 请求顺序变得反直觉:只有达到 CONCURRENT_REQUESTS 前按序发送,剩余 start 请求按逆序发送
SCHEDULER_START_MEMORY_QUEUE 'scrapy.squeues.FifoMemoryQueue' 调度器为 start requests 使用的内存队列,同样可用 None/"" 禁用独立队列

DUPEFILTER_CLASS 自定义示例(换用包含 X-ID 请求头的指纹):

from scrapy.dupefilters import RFPDupeFilter
from scrapy.utils.request import fingerprint


class CustomRequestFingerprinter:
    def fingerprint(self, request):
        return fingerprint(request, include_headers=["X-ID"])


class CustomDupeFilter(RFPDupeFilter):

    def __init__(self, path=None, debug=False, *, fingerprinter=None):
        super().__init__(
            path=path, debug=debug, fingerprinter=CustomRequestFingerprinter()
        )

实现自定义去重器类需遵循的接口为:类方法 from_crawler(crawler),以及 request_seen(request)(是否见过)、open()close(reason)(Spider 开/关前调用,可返回 Deferred)、log(request, spider)(记录被过滤请求)。

7.6 中间件、管道与契约

设置项 默认值 说明
DOWNLOADER_MIDDLEWARES {} 项目启用的下载器中间件及顺序(组件优先级字典)
DOWNLOADER_MIDDLEWARES_BASE 见下 Scrapy 默认启用的下载器中间件。不应修改,改 DOWNLOADER_MIDDLEWARES。低序号靠近引擎,高序号靠近下载器
SPIDER_MIDDLEWARES {} 项目启用的 Spider 中间件及顺序
SPIDER_MIDDLEWARES_BASE 见下 默认启用的 Spider 中间件。低序号靠近引擎,高序号靠近 Spider
ITEM_PIPELINES {} 项目使用的物品管道及顺序;顺序值任意但惯例在 0–1000,小值先处理
ITEM_PIPELINES_BASE {} 默认启用的管道。不应修改,改 ITEM_PIPELINES
ITEM_PROCESSOR "scrapy.pipelines.ItemPipelineManager" 依据 ITEM_PIPELINES 构建管道并让物品通过它的组件,须实现 ItemProcessorProtocol
SPIDER_CONTRACTS {} 项目启用的 Spider 契约字典(用于 Spider 测试)。可用 {"scrapy.contracts.default.ScrapesContract": None} 禁用内置契约
SPIDER_CONTRACTS_BASE 见下 默认启用的契约。不应修改,改 SPIDER_CONTRACTS

DOWNLOADER_MIDDLEWARES_BASE 默认值(注意 UserAgentMiddleware 为 500、RetryMiddleware 为 550、CookiesMiddleware 为 700 等顺序):

{
    "scrapy.downloadermiddlewares.offsite.OffsiteMiddleware": 50,
    "scrapy.downloadermiddlewares.robotstxt.RobotsTxtMiddleware": 100,
    "scrapy.downloadermiddlewares.httpauth.HttpAuthMiddleware": 300,
    "scrapy.downloadermiddlewares.downloadtimeout.DownloadTimeoutMiddleware": 350,
    "scrapy.downloadermiddlewares.defaultheaders.DefaultHeadersMiddleware": 400,
    "scrapy.downloadermiddlewares.useragent.UserAgentMiddleware": 500,
    "scrapy.downloadermiddlewares.retry.RetryMiddleware": 550,
    "scrapy.downloadermiddlewares.redirect.MetaRefreshMiddleware": 580,
    "scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware": 590,
    "scrapy.downloadermiddlewares.redirect.RedirectMiddleware": 600,
    "scrapy.downloadermiddlewares.cookies.CookiesMiddleware": 700,
    "scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 750,
    "scrapy.downloadermiddlewares.stats.DownloaderStats": 850,
    "scrapy.downloadermiddlewares.httpcache.HttpCacheMiddleware": 900,
}

SPIDER_MIDDLEWARES_BASE 默认值:

{
    "scrapy.spidermiddlewares.start.StartSpiderMiddleware": 25,
    "scrapy.spidermiddlewares.httperror.HttpErrorMiddleware": 50,
    "scrapy.spidermiddlewares.referer.RefererMiddleware": 700,
    "scrapy.spidermiddlewares.urllength.UrlLengthMiddleware": 800,
    "scrapy.spidermiddlewares.depth.DepthMiddleware": 900,
}

SPIDER_CONTRACTS_BASE 默认值:

{
    "scrapy.contracts.default.UrlContract": 1,
    "scrapy.contracts.default.CallbackKeywordArgumentsContract": 1,
    "scrapy.contracts.default.MetadataContract": 1,
    "scrapy.contracts.default.ReturnsContract": 2,
    "scrapy.contracts.default.ScrapesContract": 3,
}

ITEM_PIPELINES 示例:

ITEM_PIPELINES = {
    "mybot.pipelines.validate.ValidateMyItem": 300,
    "mybot.pipelines.validate.StoreMyItem": 800,
}

7.7 扩展、内存与统计

设置项 默认值 说明
EXTENSIONS {} 启用的扩展组件优先级字典
EXTENSIONS_BASE 见下 Scrapy 默认包含的全部稳定内置扩展(注意其中部分还需通过设置启用)
TELNETCONSOLE_ENABLED TrueTWISTED_REACTOR_ENABLED=False 时为 False 是否启用 telnet 控制台(还需其扩展被启用)
MEMUSAGE_ENABLED True(Scope: scrapy.extensions.memusage.MemoryUsage 是否启用内存使用扩展:跟踪进程峰值内存并写入统计,超出限制时可关闭 Scrapy
MEMUSAGE_LIMIT_MB 0(同上 Scope) 允许的最大内存(MB),超出即关闭 Scrapy;0 表示不检查
MEMUSAGE_WARNING_MB 0(同上 Scope) 触发 memusage_warning_reached 信号的内存上限(MB);0 表示不发送信号
MEMUSAGE_CHECK_INTERVAL_SECONDS 60.0(同上 Scope) 内存检查的时间间隔(秒)
MEMDEBUG_ENABLED False 是否启用内存调试
STATS_CLASS 'scrapy.statscollectors.MemoryStatsCollector' 收集统计的类,须实现 Stats 接口
STATS_DUMP True Spider 结束时把 Scrapy 统计转储到日志
LOGSTATS_INTERVAL 60.0 LogStats 扩展打印统计的间隔(秒)

EXTENSIONS_BASE 默认值:

{
    "scrapy.extensions.corestats.CoreStats": 0,
    "scrapy.extensions.logcount.LogCount": 0,
    "scrapy.extensions.telnet.TelnetConsole": 0,
    "scrapy.extensions.memusage.MemoryUsage": 0,
    "scrapy.extensions.memdebug.MemoryDebugger": 0,
    "scrapy.extensions.closespider.CloseSpider": 0,
    "scrapy.extensions.feedexport.FeedExporter": 0,
    "scrapy.extensions.logstats.LogStats": 0,
    "scrapy.extensions.spiderstate.SpiderState": 0,
    "scrapy.extensions.throttle.AutoThrottle": 0,
    "scrapy.extensions.remote_control.RemoteControl": 0,
}

7.8 日志

设置项 默认值 说明
LOG_ENABLED True 是否启用日志(日志设置)
LOG_LEVEL 'DEBUG' 最低记录级别:CRITICAL、ERROR、WARNING、INFO、DEBUG(日志设置)
LOG_ENCODING 'utf-8' 日志编码(日志设置)
LOG_FILE None 日志输出文件名;None 时输出到标准错误(日志设置)
LOG_FILE_APPEND True FalseLOG_FILE 指定的文件被覆盖(丢弃之前运行的输出)(日志设置)
LOG_FORMAT '%(asctime)s [%(name)s] %(levelname)s: %(message)s' 日志消息格式字符串(日志设置)
LOG_DATEFORMAT '%Y-%m-%d %H:%M:%S' %(asctime)s 占位符的日期/时间格式(日志设置)
LOG_FORMATTER scrapy.logformatter.LogFormatter 用于对不同动作格式化日志消息的类
LOG_STDOUT False True 时进程全部标准输出/错误都重定向到日志(例如 print('hello') 会出现在 Scrapy 日志中)(日志设置)
LOG_SHORT_NAMES False True 时日志只包含根路径;False 时显示产生日志的组件全名(日志设置)
LOG_VERSIONS ["lxml", "libxml2", "cssselect", "parsel", "w3lib", "Twisted", "Python", "pyOpenSSL", "cryptography", "Platform"] 记录指定项的已安装版本;项可以是任意已安装的 Python 包,另支持特殊项 libxml2Platformplatform.platform)、PythonpyOpenSSL
DEFAULT_DROPITEM_LOG_LEVEL "WARNING" 物品被管道 process_item 抛出 DropItem 丢弃时的默认日志级别。可传整数(如 20)、级别常量(如 logging.INFO)或名称字符串(如 "INFO")。写管道时可通过 DropItemlog_level 属性强制不同级别

DropItem 自定义日志级别示例:

from scrapy.exceptions import DropItem


class MyPipeline:
    def process_item(self, item):
        if not item.get("price"):
            raise DropItem("Missing price data", log_level="INFO")
        return item

7.9 深度、优先级与 URL 长度

设置项 默认值 说明
DEPTH_LIMIT 0(Scope: DepthMiddleware 允许的最大爬取深度;0 表示不限制
DEPTH_PRIORITY 0(Scope: DepthMiddleware 依据深度调整请求优先级的整数:request.priority = request.priority - (depth * DEPTH_PRIORITY)。正值使深度增加时优先级降低(BFO,广度优先),负值提高优先级(DFO)。注意:与 REDIRECT_PRIORITY_ADJUSTRETRY_PRIORITY_ADJUST 的调节方向相反
DEPTH_STATS_VERBOSE False(Scope: DepthMiddleware 是否收集每个深度的请求数详细统计
REDIRECT_PRIORITY_ADJUST +2(Scope: RedirectMiddleware 重定向请求相对原请求的优先级调整:正值(默认)表示更高优先级,负值表示更低
URLLENGTH_LIMIT 2083(Scope: scrapy.spidermiddlewares.urllength 允许爬取的最大 URL 长度,可作为 URL 不断变长(服务器或代码错误导致)时的停止条件;0 表示不限。默认值取自 Internet Explorer 最大 URL 长度(虽然本设置的目的不同)。另参见 REDIRECT_MAX_TIMESDEPTH_LIMIT

7.10 robots.txt

设置项 默认值 说明
ROBOTSTXT_OBEY True(fallback: False 启用后遵守 robots.txt 策略。历史原因默认是 False,但 startproject 生成的 settings.py 中已启用
ROBOTSTXT_PARSER 'scrapy.robotstxt.ProtegoRobotParser' 解析 robots.txt 的后端类
ROBOTSTXT_USER_AGENT None 在 robots.txt 中用于匹配的 User-Agent 字符串。None 时按序使用请求的 User-Agent 头、USER_AGENT 设置来确定

7.11 Feed 导出与云存储(AWS/GCS)

设置项 默认值 说明
FEED_TEMPDIR None 使用 FTP / Amazon S3 存储上传前,保存爬取临时文件的自定义目录
FEED_STORAGE_GCS_ACL "" 存储物品到 Google Cloud Storage 时使用的 ACL
GCS_PROJECT_ID None 存储数据到 Google Cloud Storage 时使用的 Project ID
AWS_ACCESS_KEY_ID None 访问 AWS(如 S3 feed 存储)使用的 access key
AWS_SECRET_ACCESS_KEY None 访问 AWS 使用的 secret key
AWS_SESSION_TOKEN None 使用临时安全凭证时访问 AWS 使用的安全 token
AWS_REGION_NAME None AWS 客户端关联的区域名
AWS_ENDPOINT_URL None S3 类存储(如 Minio、s3.scality)的端点 URL
AWS_USE_SSL None 设为 False 可禁用与 S3/S3 类存储通信的 SSL 连接(默认使用 SSL)
AWS_VERIFY None 是否验证 Scrapy 与 S3/S3 类存储之间的 SSL 连接(默认验证)
AWS_MAX_POOL_CONNECTIONS None(2.18 起新增) S3 feed 存储与 S3 媒体管道等 AWS 客户端连接池的最大连接数;None 时使用 REACTOR_THREADPOOL_MAXSIZE 的值。低于并行 AWS 调用数的值不会限制调用,但连接被丢弃而非复用(影响性能)并记录 Connection pool is full, discarding connection 警告

除上述设置外,部分设置(如自动限流、Feed 导出各格式参数、Cookie 持久化等)在各自专题文档(docs/topics/ 下的 autothrottle、feed-exports、cookies 等章节)中单独说明,启用方式与用法需按具体设置查阅对应章节。

8. 实操要点回顾

综合以上内容,日常配置 Scrapy 时最常使用的模式可归纳为:

  1. 限速与礼貌抓取三件套DOWNLOAD_DELAY(支持小数)+ RANDOMIZE_DOWNLOAD_DELAY(默认启用,0.5–1.5 倍随机)+ CONCURRENT_REQUESTS_PER_DOMAIN(新项目默认 1),需要按域差异化时用 DOWNLOAD_SLOTS
  2. 叠加而非覆盖:项目级中间件/管道配置写入 DOWNLOADER_MIDDLEWARESITEM_PIPELINES 等,框架自动与对应 _BASE 合并(源码见 get_component_priority_dict_with_base),禁用内置组件一律赋 None,切勿修改 _BASE
  3. 一次性覆盖:调试时用 -s KEY=value 命令行覆盖(最高优先级 cmdline=40),注意字符串值的读取要用 getbool/getint 等转换方法;
  4. Spider 级定制:静态值用 custom_settings,动态值用 update_settings(显式 priority="spider")或 from_crawler,但注意预爬虫设置、Reactor 设置与日志设置的限制边界。

所有全局默认值定义在 scrapy/settings/default_settings.py,优先级机制与类型转换 API 的完整实现可在 scrapy/settings/init.py 中查证;startproject 生成的项目级模板见 scrapy/templates/project/module/settings.py.tmpl,可作为编写自己 settings.py 的参照。

登录后查看全文
热门项目推荐
相关项目推荐