5月31日 00:56

Scrapy 爬虫运行中如何监控和定位问题?

Scrapy 监控要回答三个问题:爬虫是否还活着,数据产出是否正常,异常卡在哪一步。只看进程状态不够,因为进程可能还在跑,却一直拿到 403、验证码、空页面或登录页。生产环境至少要看请求量、状态码、失败率、item 数、入库数、运行耗时、队列积压和内存占用。指标少一点没关系,但每个指标都要能指导动作。

先用 Stats 建基础盘

Scrapy 自带 Stats Collector,会记录请求、响应、重试、异常和 item 数。最小成本的做法是在爬虫结束时把关键指标写进日志或监控系统。item_scraped_count 看产出,downloader/response_status_count/403 看封禁,downloader/exception_type_count/* 看网络异常。

python
class StatsPipeline: def close_spider(self, spider): s = spider.crawler.stats.get_stats() spider.logger.info({ "items": s.get("item_scraped_count", 0), "requests": s.get("downloader/request_count", 0), "errors": s.get("log_count/ERROR", 0), })

日志要能还原现场

本地调试可以用 DEBUG,线上默认 INFO,关键异常才打 ERROR。日志里要带 spider、任务参数、URL、状态码、代理标识、解析阶段和 item 主键。不要把 Cookie、Token、手机号直接打到日志里,集中日志平台会放大泄露风险。

python
LOG_LEVEL = "INFO" LOG_FORMAT = "%(asctime)s [%(name)s] %(levelname)s: %(message)s" RETRY_HTTP_CODES = [429, 500, 502, 503, 504, 408]

日志采集可以用 ELK、Loki,也可以先用本地滚动文件。边界是小项目不用一开始上大平台,但必须设置切割和保留天数,别让日志写满磁盘。

用 Scrapyd API 做运行管理

Scrapyd API 能查看任务、取消任务和读取日志,适合接内部管理后台。Telnet Console 适合临时排查运行中的 crawler 和 stats,但不要暴露公网。排查顺序建议从请求入口开始:先看状态码和响应内容,再看选择器,最后看 pipeline 和入库。

bash
curl http://127.0.0.1:6800/listjobs.json?project=news_crawler curl http://127.0.0.1:6800/cancel.json -d project=news_crawler -d job=JOB_ID

告警围绕业务结果

告警不应只看崩溃。更有价值的是 30 分钟无新增、字段为空率升高、详情页成功率下降、重复率异常、磁盘快满。阈值先按一两周基线设置,别一开始太敏感,否则团队很快会忽略告警。

追问

Scrapy 自带 stats 够用吗?

基础监控够用,比如请求数、状态码、重试、异常和 item 数。业务指标不够,比如字段为空率、价格异常和入库失败原因。它们应该在 pipeline 或 middleware 里补。边界是明细不要全塞指标,单 URL 细节更适合日志。

item 数突然变 0 怎么查?

先看请求是否成功,再看 403、429、302 是否异常。然后保存一条响应,确认是不是验证码、登录页或页面结构变化。最后再改 XPath 或 CSS 选择器。常见坑是直接改解析规则,真实原因却是代理池失效。

日志和指标有什么区别?

指标适合看趋势和触发告警,比如错误率上升。日志适合还原现场,比如某个 URL 为什么失败。只靠日志会被细节淹没,只靠指标又解释不了原因。取舍上,指标要稳定,日志要可检索。

Telnet Console 能在线上开吗?

能开,但必须限制监听地址和访问来源。它对查看 crawler、engine、stats 很方便。风险是权限太大,暴露出去等于把运行进程交给别人。更稳妥的是内网临时开启,排查结束关闭。

告警太多没人看怎么办?

删掉没有行动价值的告警,比如单次超时。保留连续无产出、失败率持续升高、磁盘快满这类会影响结果的问题。告警内容要带 spider、版本、任务参数和日志位置。踩坑是只告警失败不告警恢复,大家不知道问题是否结束。

标签:Scrapy