Scrapy 设置系统详解:六层优先级栈、特殊设置机制与内置设置项全参考
Scrapy 的 Settings(设置系统)是整个框架的配置中枢:它以带优先级的键值命名空间,统一驱动下载器、中间件、管道、扩展与 Spider 本身的行为。本文基于官方文档 docs/topics/settings.rst 与源码 scrapy/settings/__init__.py、scrapy/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_settings(scrapy/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_settings 是 Spider 基类的类方法(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 为 8;DOWNLOAD_DELAY 默认为 1、fallback 为 0;ROBOTSTXT_OBEY 默认为 True、fallback 为 False(历史原因导致默认是 False,但 startproject 生成的 settings.py 中已启用它)。
4. 组件优先级字典:中间件/管道/扩展的统一编排结构
**组件优先级字典(component priority dictionary)**是一个字典:键是组件(可以是类对象或导入路径字符串),值是组件优先级(int 或 None):
{
"path.to.ComponentA": None,
ComponentB: 100,
}
三条核心规则:
- 优先级数字越小越靠前(优先级 1 的组件在优先级 2 之前)。但"在前"的具体含义取决于对应设置——例如在
DOWNLOADER_MIDDLEWARES中,靠前的组件其process_request方法先于靠后组件执行,而其process_response方法则后于靠后组件执行; - 优先级为
None表示禁用该组件; - 某些组件优先级字典会与内置的
_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' 返回 True;0/'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 设置。包括:
ADDONSCOMMANDS_MODULEFORCE_CRAWLER_PROCESSSPIDER_LOADER_CLASS及对应 Spider 加载器类使用的设置,如默认加载器的SPIDER_MODULES、SPIDER_LOADER_WARN_ONLYTWISTED_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_ENABLED、DNSCACHE_SIZE、DNS_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_REACTOR 或 ASYNCIO_EVENT_LOOP 会抛出异常。除 ASYNCIO_EVENT_LOOP 外,这些设置都只在 TWISTED_REACTOR_ENABLED 为 True(即使用 Twisted reactor)时生效。
6.3 日志设置
日志设置配置由 scrapy.utils.log.configure_logging 安装的全局根日志处理器。它们可以由 Spider 定义,但由于一个进程只有一个活动的根日志处理器,同进程多 Spider 时不能按 Spider 取不同值。共 9 项:
LOG_DATEFORMAT、LOG_ENABLED、LOG_ENCODING、LOG_FILE、LOG_FILE_APPEND、LOG_FORMAT、LOG_LEVEL、LOG_SHORT_NAMES、LOG_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 时,是否在 AsyncCrawlerProcess 与 CrawlerProcess 间按 TWISTED_REACTOR 值自动选择(False)还是始终用 CrawlerProcess(True)。若想在 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_DELAY 到 1.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 抛出 ResponseDataLossError;False 则放行并在 response.flags 中加入 dataloss。可经 meta 键 download_fail_on_dataloss 按请求设为 False。若 RETRY_ENABLED 为 True 且本设为 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 帧大小(字节),介于 16384 与 16777215 之间;服务器发送更大帧时连接失败。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_DELAY → delay,CONCURRENT_REQUESTS_PER_DOMAIN → concurrency,RANDOMIZE_DOWNLOAD_DELAY → randomize_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_TIMEOUT。TWISTED_REACTOR_ENABLED=False 时无效。Reactor 设置 |
DNSCACHE_ENABLED |
True |
是否启用 DNS 内存缓存。仅 CachingThreadedResolver 与 CachingHostnameResolver 使用;无 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' |
调度器使用的磁盘队列类型,另有 PickleFifoDiskQueue、MarshalFifoDiskQueue、MarshalLifoDiskQueue |
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 |
True(TWISTED_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 |
为 False 时 LOG_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 包,另支持特殊项 libxml2、Platform(platform.platform)、Python、pyOpenSSL |
DEFAULT_DROPITEM_LOG_LEVEL |
"WARNING" |
物品被管道 process_item 抛出 DropItem 丢弃时的默认日志级别。可传整数(如 20)、级别常量(如 logging.INFO)或名称字符串(如 "INFO")。写管道时可通过 DropItem 的 log_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_ADJUST、RETRY_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_TIMES 与 DEPTH_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 时最常使用的模式可归纳为:
- 限速与礼貌抓取三件套:
DOWNLOAD_DELAY(支持小数)+RANDOMIZE_DOWNLOAD_DELAY(默认启用,0.5–1.5 倍随机)+CONCURRENT_REQUESTS_PER_DOMAIN(新项目默认1),需要按域差异化时用DOWNLOAD_SLOTS; - 叠加而非覆盖:项目级中间件/管道配置写入
DOWNLOADER_MIDDLEWARES、ITEM_PIPELINES等,框架自动与对应_BASE合并(源码见 get_component_priority_dict_with_base),禁用内置组件一律赋None,切勿修改_BASE; - 一次性覆盖:调试时用
-s KEY=value命令行覆盖(最高优先级cmdline=40),注意字符串值的读取要用getbool/getint等转换方法; - 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 的参照。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00