Scrapyd部署实战:从本地爬虫到线上调度与监控

发布时间:2026/10/17 9:51:17
Scrapyd部署实战:从本地爬虫到线上调度与监控 1. Scrapyd 部署是什么能解决什么问题1.1 本地跑爬虫和线上跑爬虫根本是两个世界先聊个很多人都踩过的场景。你在本地把 Scrapy 爬虫调通了数据正常入库日志干净漂亮觉得万事大吉。然后把代码传到服务器用scrapy crawl xxx一跑问题全来了爬虫跑了一会儿进程挂了没人管想定时启动没有统一入口多个爬虫同时跑资源互相抢占代码更新一次还要手动去服务器上拉代码、重启进程。我之前见过一个同学线上爬虫挂了三天愣是没发现等到数据报表对不上才反应过来——这种时候光靠nohup和crontab硬扛迟早出事。Scrapyd 解决的就是这个问题。它是 Scrapy 官方配套的部署与调度服务可以把爬虫项目打包上传到服务器上通过它提供的 HTTP 接口来启停爬虫、查看状态、管理版本。换句话讲Scrapyd 就是给你的爬虫群装了一个调度总机部署、运行、监控都在这个统一的入口上完成。1.2 核心能力拆解打包、上传、调度三件套Scrapyd 能做的事从使用角度可以拆成三个层面项目打包本地执行一条命令当前爬虫项目会被打成 egg 包这个包就是项目在服务器上的版本快照。项目上传打包好的 egg 包会通过 Scrapyd 的 API 上传到服务端Scrapyd 自动解包、注册版本替代旧版本。任务调度通过/schedule.json接口触发爬虫运行通过/listjobs.json查询任务执行情况随时可以取消或重启。它适合谁来用在我看来只要你的爬虫不是跑一次就扔的一次性脚本而是需要长期维护、持续采集、多任务并行的项目就应该尽早把 Scrapyd 纳入技术栈。尤其是负责数据采集的工程师或者自己搭数据系统的独立开发者早一天用上这玩意儿早一天摆脱翻服务器日志查进程的苦日子。2. 部署之前的准备工作一张清单讲透2.1 环境与版本匹配别让细节卡住流程先说环境的硬性要求。Scrapyd 本身是一个 Python 包安装命令很简单但有几个版本上的坑需要注意。我用得比较稳的组合是Python 3.8 及以上版本、Scrapy 2.x、Scrapyd 1.2.x。如果你用的是 Scrapy 2.5 以上版本配合 Scrapyd 1.2.0 以上基本没有问题。这里要特别提醒一点Scrapyd 在 1.2 版本之后更新比较慢官方文档一直比较简略很多人初次接触时容易轻视它实际部署时遇到问题才意识到文档之外还有很多细节。安装命令如下pip install scrapyd scrapyd-client注意这个scrapyd-client它就是提供scrapyd-deploy命令的包。当年我刚开始学习的时候只装了一个scrapyd然后到处找scrapyd-deploy后来才明白这两个是分开的。scrapyd是服务端跑在服务器上scrapyd-client是客户端工具跑在你本地开发机上负责打包和上传。安装完成后需要看一下版本是否对齐scrapyd version scrapyd-deploy -l如果scrapyd-deploy提示找不到命令大概率是 Python 的 Scripts 目录没进 PATH把 Python 安装目录下的 Scripts 文件夹加到环境变量即可。2.2 项目结构规范化Scrapyd 部署的第一道门槛在部署之前必须确认你的 Scrapy 项目结构是标准的。什么叫标准就是通过scrapy startproject创建出来的结构myproject/ ├── scrapy.cfg ├── myproject/ │ ├── __init__.py │ ├── items.py │ ├── middlewares.py │ ├── pipelines.py │ ├── settings.py │ └── spiders/ │ ├── __init__.py │ └── myspider.pyscrapy.cfg这个文件是部署配置的核心。默认内容大致如下[settings] default myproject.settings [deploy] url http://localhost:6800/ project myproject注意[deploy]这个段落在新建项目时并不默认存在需要手动加。如果你的项目没有这个段落scrapyd-deploy会直接报错找不到部署目标。我当时第一次部署时就是卡在这个环节还以为是代码的问题折腾了半天才反应过来是配置文件缺了部署信息。如果只有一个部署目标配置写在[deploy]下面即可。如果想区分测试环境和生产环境可以写成[deploy:test]、[deploy:prod]这种带标签的形式比如[deploy:test] url http://192.168.1.100:6800/ project myproject [deploy:prod] url http://your-server-ip:6800/ project myproject这样之后就可以用scrapyd-deploy test -p myproject或scrapyd-deploy prod -p myproject区分发布目标。这种方式在项目多、环境多的时候特别好用推荐养成这个习惯。3. 本地部署实操全流程3.1 服务端启动第一道配置关卡先说服务端。在你的服务器上安装好scrapyd之后默认配置下直接运行scrapyd它会监听0.0.0.0:6800端口并生成一个默认的配置文件。这个配置文件在 Linux 系统上通常位于/etc/scrapyd/scrapyd.conf在 macOS 上位于scrapyd启动目录下的scrapyd.conf。默认配置内容大致是[scrapyd] eggs_dir eggs logs_dir logs items_dir items jobs_to_keep 5 dbs_dir dbs max_proc 0 max_proc_per_cpu 4 finished_to_keep 100 poll_interval 5.0 bind_address 0.0.0.0 http_port 6800 debug off几个关键参数我给新手讲一下max_proc允许并发运行的进程数0 表示不限制按照 CPU 核心数自动决定。对于大多数场景保持默认即可。max_proc_per_cpu每个 CPU 核心最多同时运行的进程数默认 4。如果你的服务器配置一般建议调低到 2防止内存被打满。poll_interval轮询间隔Scrapyd 检查任务队列的间隔秒数默认 5 秒。jobs_to_keep每个项目保留多少个最近完成的 job 记录。finished_to_keep完成的 job 记录保留数量。用浏览器访问http://localhost:6800/如果能看到一个简单的页面并在页面上列出可用接口说明服务端已经正常启动。需要注意的是如果你要让其他机器也能访问需要确保bind_address是0.0.0.0同时放行 6800 端口。我在云服务器上部署时经常遇到服务本身没毛病、但外网访问不了的问题最后排查下来都是安全组和防火墙规则挡了端口。3.2 本地打包与部署scrapyd-deploy 的完整用法服务端就绪后回到本地项目目录执行scrapyd-deploy -p myproject如果你的scrapy.cfg里只有一个 deploy 目标并且项目名已经写好可以直接用scrapyd-deploy执行成功后你会看到这样的输出Packing version: 1651234567 Deploying to project myproject in http://127.0.0.1:6800/addversion.json Server response (200): {status: ok, spiders: 2, node_name: xxx, project: myproject, version: 1651234567}这里有几个信息值得关注。version那一串数字是时间戳Scrapyd 用它来标识不同的部署版本。如果你对版本有自定义需求可以加--version参数scrapyd-deploy -p myproject --version v1.0.0spiders: 2表示 Scrapyd 识别到了两个爬虫这个数字可以用来验证你的爬虫包是否被正确解析。如果这里的数字和你预期的爬虫数量对不上说明项目打包时出问题了或者爬虫本身有导入错误。有时你会在输出中看到Deploying failed或者Unhandled Error这种情况最常见的原因是网络不通或者服务端的 egg 存储目录权限不对。遇到 500 错误时先查服务端日志不要从本地反复试。3.3 用 API 远程调度爬虫任务项目部署上去之后触发爬虫不再需要登录服务器敲命令。通过 HTTP API 就能完成curl http://localhost:6800/schedule.json -d projectmyproject -d spidermyspider返回结果{status: ok, jobid: xxxxxxxxx}这个jobid就是本次任务的唯一标识后续查询、取消任务都要用到它。查询任务状态curl http://localhost:6800/listjobs.json?projectmyproject返回数据里包含running、pending、finished三个列表分别对应运行中、排队中和已完成的任务。我曾遇到过一个任务一直显示pending开始还以为是调度出了问题后来发现是因为同时提交的任务太多超过了max_proc_per_cpu的限制任务在排队等待。这种时候listjobs.json就能帮你快速判断是排队还是卡死。取消任务用/cancel.jsoncurl http://localhost:6800/cancel.json -d projectmyproject -d jobjobid如果说本地调试阶段你还可以对着终端看日志那么一旦上了 Scrapyd日志文件就变成了远程文件。每个任务日志存放在服务器的logs目录下路径规则是logs/project/spider/jobid.log用scrapyd-deploy部署后这些日志的位置由服务端的logs_dir配置决定。3.4 关于日志查看很多人忽略的两个细节第一个细节是日志轮转。长时间运行的爬虫会产生很大的日志文件Scrapyd 本身不处理日志切割。我的习惯是在服务器上配一个logrotate规则按天切割保留最近 7 天避免磁盘被日志塞满。这个不配的话爬虫跑一两个月一个 log 文件动辄几个 GB排查问题的时候连打开都费劲。第二个细节是 Scrapy 的日志级别调整。在settings.py里加上LOG_LEVEL INFO并且在LOG_FORMAT中带上时间戳这样远程日志才有排查价值。如果是 DEBUG 级别日志量会非常大而且 Scrapyd 调度下控制台日志不会被打印只看文件日志所以合理的日志级别很关键。4. 生产环境下的部署进阶方案4.1 单机多项目部署资源隔离是重点很多人以为 Scrapyd 只能部署一个项目实际上它支持多个项目共存。上传不同项目名的 egg 包即可互不干扰。不过多项目共用一台服务器时最怕的是某个爬虫内存失控把整台机器拖垮。我个人的经验是在配置里根据爬虫的重要程度调整并发参数。比如核心爬虫项目可以单独部署一个 Scrapyd 实例次要爬虫用另一个实例这样即使次要任务出问题也不会影响核心数据采集。开启第二个实例只需要指定不同的端口scrapyd -p 6801同时要准备不同的配置文件或用环境变量指向不同配置。这种方式初始化成本不高但隔离效果立竿见影。4.2 多机扩展从单机到分布式的迁移路径当你的采集规模变大单机已经不够用时就需要考虑多机部署。Scrapyd 本身没有集群的概念但可以搭建一个简单的分布式调度体系。最朴素的做法是多台服务器各自跑一个 Scrapyd 实例用同一套scrapy.cfg配置多个 deploy 目标把代码分别部署到各台机器上。然后由一个中心调度程序统一调用各机器的/schedule.json接口按负载情况将任务分发到不同机器。这个方案不引入额外复杂组件只用一个管理脚本就能跑通。具体调度策略可以很简单比如轮询分发或者根据各机器的listjobs.json结果把任务分给运行中任务最少的那台。我当时用几个核心指标做判断当前任务数、服务器负载、任务队列长度。这些都是通过接口实时读取的实现难度不高但带来了明显的吞吐提升。4.3 部署流程自动化少踩手动操作的坑开发环境部署一个爬虫项目可能一天会发生好几次。每次敲一遍scrapyd-deploy其实还好但生产环境频繁手动部署风险很大——一旦部署了包含 bug 的版本线上爬虫全部挂掉排查和回滚都要花时间。我的建议是给部署加上版本管理和回滚能力。每次部署使用有意义的版本号比如带上 git commit 的短 hashscrapyd-deploy -p myproject --version $(git rev-parse --short HEAD)这样在出问题时你可以回滚到之前的某个版本。Scrapyd 支持保留多个版本但只有最新版本会被用于新任务。如果要回滚重新部署旧版本的代码即可。完整一点的自动化流程可以在 CI 里配置两个步骤先跑语法检查和单元测试再执行部署命令。别嫌这两个步骤简单我吃过一次亏本地代码没问题但部署到服务器后发现忘了把某个爬虫文件提交到仓库CI 打包时直接少了一个爬虫。如果部署前有测试环节这个问题完全可以在发布前发现。5. 常见问题与排查实录5.1 部署失败高频问题速查表我在学习和带团队的过程中总结了下面这一批高频问题每一个都是实际踩过的坑现象可能原因解决思路scrapyd-deploy提示找不到命令未安装scrapyd-client或 Scripts 未入 PATH安装scrapyd-client检查环境变量部署时连接被拒绝服务端未启动或 6800 端口被防火墙拦截确认服务端运行状态检查防火墙规则返回 500日志中有文件权限错误egg 存储目录不可写给eggs、dbs等目录授权部署成功但spiders数量为 0项目代码有导入错误爬虫模块加载失败在本地执行scrapy list验证爬虫能否正常列出任务一直处于pending状态并发进程数达到上限调整max_proc配置或减少同时提交的任务数爬虫运行了但没有任何输出日志输出到文件终端看不到查看logs目录下的.log文件部署时版本总是相同时间戳导致覆盖重复执行部署命令使用自定义版本号或加入 git commit hash这张表我建议保存下来。很多东西在你只部署一两次时根本碰不到等真正在生产环境出问题时这些经验能帮你省下大把排查时间。5.2 一个真实的排查案例任务卡死的全过程这里分享一个我印象比较深的案例。一个采集任务在本地跑得好好的部署到 Scrapyd 后一开始正常运行到某个数据页后进程直接卡死。通过listjobs.json查看任务状态显示running但日志已经很久没有新输出。排查过程大概是这样的先看日志确认卡住的时间点然后还原现场模拟那一段时间的数据请求发现目标网站在某个特定条件下会长时间不返回响应而 Scrapy 默认的下载超时是 180 秒在这期间任务会一直等待表现为卡死。解决办法是在settings.py里加上DOWNLOAD_TIMEOUT 30同时开启了自动重试RETRY_TIMES 3这样遇到长时间无响应的请求爬虫会主动放弃并重试而不是无限期等待。问题解决后我又顺手在爬虫里加了一个统计中间件把每个请求的响应时间打到日志里。以后遇到类似问题不用瞎猜直接看日志就能定位是哪个域名响应慢。这个案例让我意识到用上 Scrapyd 之后爬虫本地没问题这句话就不再值得依赖。调度系统会把你的爬虫扔到各种真实网络环境里跑超时、反爬、资源竞争这些新问题会不断出现日志和监控体系必须跟上。5.3 Scrapyd 的局限与替代方案的思考Scrapyd 不是万能的。它没有内置可视化管理界面虽然可以借助第三方工具或者写简单前端来展示任务状态但和成熟的分布式调度系统相比功能还是单薄很多。比如它没有定时调度功能只提供了任务触发的 API。定时任务需要你用cron或外部调度器比如caddy、systemd timer去调用/schedule.json接口。此外对于任务失败后的自动重试和告警Scrapyd 也不具备需要自己封装。如果你只是个人使用或者团队规模比较小Scrapyd 完全够用而且它简单、稳定、可控。当业务规模大到需要可视化监控、任务编排和自动伸缩时再考虑更重型的工作流调度平台也不迟。我的建议是起步阶段用 Scrapyd把核心逻辑跑通积累数据等到觉得维护成本开始变高的时候再去迁移到更复杂的系统。用错了工具比没有工具更难受这个判断标准我一直记着。6. 部署过程中的几条硬核经验6.1 版本号策略时间戳之外的另一种选择前面提过Scrapyd 默认用时间戳作为版本号。但当你需要回滚到历史版本时一堆时间戳根本分不清哪个对应哪次代码变更。我的做法是在打包部署时把版本号设为代码仓库的 commit 短 hash这样每个版本号直接对应当前代码状态。部署后如果需要回溯listversions.json可以查看所有版本curl http://localhost:6800/listversions.json?projectmyproject输出会列出所有已部署的版本号以及每个版本对应的爬虫数量。这里的spiders计数也可以用来自动化校验部署是否完整。6.2 scrapy.cfg 与多环境配置的管理技巧当项目既要在本地开发又要部署到测试服和生产服时我一般会把配置抽到环境变量里。比如[deploy:prod] url http://your-server-ip:6800/ project myproject但不同的环境可能会有不同的settings.py比如数据库地址、代理配置Scrapyd 本身不支持部署时动态切换配置。我的做法是在项目中加一个settings_prod.py在部署前用环境变量或启动参数指定加载哪个配置。在爬虫启动时通过命令行参数传入curl http://localhost:6800/schedule.json -d projectmyproject -d spidermyspider -d settingPROD_SETTINGSScrapyd 的/schedule.json支持在参数中传递setting它会被注入到 Scrapy 的 settings 中。这就意味着不同的任务可以用不同的配置而不需要重新部署项目。实际操作时我通常这样写curl http://localhost:6800/schedule.json -d projectmyproject -d spidermyspider -d settingDOWNLOAD_DELAY3.0 -d settingCONCURRENT_REQUESTS8这个功能对于首次调试参数很有用。比如某个爬虫近期被对方站点限流我不需要改代码重新部署直接临时调低并发和增加下载延迟观察效果确认没问题后再固化到代码里。6.3 监控与告警没有监控的调度都是裸奔部署完 Scrapyd 后我强烈建议立刻把监控补上越早越好。最基础的三块端口存活监控定期探测 6800 端口服务挂掉时第一时间收到通知。任务失败监控调用listjobs.json统计 finished 任务中状态异常的数量异常时触发告警。数据量监控根据业务数据量比如入库条数判断爬虫是否正常工作。有时候任务执行成功但数据条数异常减少这说明可能有页面结构变更或反爬规则变化这种问题单看任务状态是发现不了的。我在实际项目里用的是最朴素的方案一个定时脚本每 5 分钟调用一次listjobs.json把关键指标写进日志再通过媒体通知推送异常。这个方案的搭建成本非常低但带来的安全感是实打实的。想想看以前排查爬虫问题要登录服务器、翻进程、看日志现在只需要看监控报表服务分布、任务状态、成功数量一目了然。这就是 Scrapyd 部署带给我的最大收益——把靠感觉运维变成了看数据运维。7. 后续还可以扩展什么7.1 给 Scrapyd 配一个任务调度器前面说过Scrapyd 没有内置定时调度。如果你希望爬虫能按固定时间运行可以写一个简单的调度脚本或者用主流的调度工具。核心逻辑都很简单到点调用/schedule.json触发指定爬虫。我个人比较推荐先从系统自带的方式做起把调度脚本放在服务器上跑熟再考虑引入第三方组件。7.2 结合采集任务编排做工程化Scrapyd 完成的是部署 调度这一层再往上走一个完整的采集工程还需要数据校验、失败报警、去重调度、代理池管理等。这些东西未必都需要引入复杂系统但可以根据业务需要逐步加入。比如我在跑一些规模化采集任务时还会把 Scrapyd 的接口封装成一个小的管理 SDK方便在代码里做任务编排和状态查询。底层的 API 其实已经很稳定封装只是为了让调用侧的代码更整洁避免到处写重复的请求逻辑。说到底Scrapyd 的部署能力只是开始真正拉开差距的是你围绕它搭建的整套采集运维体系。我个人在实际操作中的体会是先跑通最小闭环再逐步添砖加瓦远比一开始就奔着完美架构去设计来得踏实。无论你是第一次部署 Scrapyd还是已经在生产环境跑了一段时间把基础概念夯实、把日志和监控体系搭好再往上叠加任何高级功能都会顺利很多。希望这篇笔记能帮你少走一点弯路。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询