bigywater.tech
Scrapy · 47

spider 参数:-a 传参与 custom_settings

scrapy crawl myspider -a category=books 里的 -a 到底把值交给了谁?为什么 page=3 变成了字符串?start_urls 能不能直接传?__init__ 要怎么写?这篇逐个实测,把最容易踩的坑列出来。

"3"
-a page=3 之后 self.page 的值(字符串,不是整数)
退出码 0
-a start_urls=字符串 时,什么都没抓却仍然正常退出
**kwargs
自己写 __init__ 时必须接收的参数

参数怎么到 spider 里

实测 · 本机执行输出
  -a category=books -a page=3:[{'category': 'books', 'page': '3', 'page_type': 'str', 'extra': '(没有)'}](class 属性 category 被覆盖;page 是字符串 “3”)
  值里带 =:[{'url': 'http://x/?a=1&b=2', 'eq': 'a=b=c'}](按第一个 = 拆分)

-a 的键值对作为关键字参数传给 spider 的构造函数,默认的 Spider.__init__ 把它们设成实例属性,同名的类属性被覆盖。

写 __init__

实测 · 本机执行输出
  推荐写法 __init__(self, category=None, **kwargs) + super().__init__(**kwargs):[{'category': 'books', 'other': '1'}]
  漏了 **kwargs:退出码 1;["TypeError: S.__init__() got an unexpected keyword argument 'other'"]

自己写 __init__ 时要接收 **kwargs 并传给 super().__init__,否则多传一个参数就 TypeError。

start_urls 之类的坑

实测 · 本机执行输出
  -a start_urls=http://…/only:退出码 0;服务器收到 [];回调 [];日志里的错误:['2026-10-12 18:45:57 [scrapy.core.engine] ERROR: Error while reading start items and requests: Missing scheme i', 'raise ValueError(f"Missing scheme in request url: {self._url}")']
  -a start_urls=[…](JSON 风格的字符串):服务器收到 []
  -a novalue(没有 =):退出码 2;['Usage', 'python -m scrapy: error: Invalid -a value, use -a NAME=VALUE']

命令行上的值总是字符串。start_urls 直接传字符串会被按字符遍历,抛 Missing scheme 却以退出码 0 结束;没有 = 的 -a 直接报参数错误。

列表型参数

实测 · 本机执行输出
  -a urls=a,b 由 __init__ 拆成 start_urls:服务器收到 ['/a', '/b']

列表要自己解析,比如逗号分隔再 split 成 start_urls。

程序里传参

实测 · 本机执行输出
  p.crawl(S, page=3, opts={…}):[{'page': 3, 'page_type': 'int', 'opts': {'k': [1, 2]}, 'opts_type': 'dict', 'setting_same_name': 'from-settings'}](类型保留;同名的设置 PAGE 是另一回事)

CrawlerProcess.crawl(S, **kwargs) 可以传任意类型,原样保留,与同名设置互不影响。

分步演示

spider 参数
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.8 / Scrapy 2.19.0 / Twisted 26.4.0 / lxml 6.1.3 / parsel 1.12.1(临时虚拟环境);所有请求只发给本机自己起的测试服务器(127.0.0.1,端口 9960 以上,不访问任何真实网站);服务器可以按实验需要制造延迟、重定向、压缩、断连等行为,并记录收到的原始请求;每个实验在临时目录里新建 Scrapy 项目或单文件 spider,命令输出来自真实的 scrapy 进程;计时用 time.perf_counter,数字每次运行会有小幅抖动。命令行用 scrapy runspider spider.py -a …;spider 在 start() 里用 EV() 记录属性;程序里启动用单文件脚本里的 CrawlerProcess
    • 没有验证:scrapy crawl(项目内)与 runspider 在参数传递上的差异(行为一致,源码里同一个 spargs);custom_settings 能否通过 -a 修改(不能,它是类属性,没有实测);参数名与 Spider 已有属性(如 name、logger、settings)冲突的后果;从 scrapyd 传参(scrapyd 会把参数转成 -a)
    京ICP备2026067502号-1京公网安备11010502063487号