bigywater.tech
Scrapy · 35

统计信息:stats 里每个数字怎么来的

抓取结束时那一大串 stats 里的每个数字怎么来的?response_count 和 response_received_count 为什么不一样?bytes 数的是什么字节?怎么加自己的统计?这篇用一次很小的抓取把 stats 逐项对账。

5 vs 4
downloader/response_count 与 response_received_count(302 被重定向中间件消费)
226 vs 221
服务器实际收到的请求字节与 downloader/request_bytes(差 Host 里的 “:端口”)
25 vs 20
结束日志里的统计项数与 spider.closed() 里读到的项数

请求与响应计数

实测 · 本机执行输出
  downloader/request_bytes                      1246
  downloader/request_count                      5
  downloader/request_method_count/GET           5
  downloader/response_bytes                     710
  downloader/response_count                     5
  downloader/response_status_count/200          3
  downloader/response_status_count/302          1
  downloader/response_status_count/404          1
  dupefilter/filtered                           1
  elapsed_time_seconds                          0.01
  finish_reason                                 finished
  finish_time                                   <datetime>
  item_scraped_count                            2
  items_per_minute                              None
  log_count/INFO                                2
  memusage/max                                  91160576
  memusage/startup                              91160576
  request_depth_max                             1
  response_received_count                       4
  responses_per_minute                          None
  scheduler/dequeued                            5
  scheduler/dequeued/memory                     5
  scheduler/enqueued                            5
  scheduler/enqueued/memory                     5
  start_time                                    <datetime>

downloader/request_count、response_count 由下载器统计中间件记;response_received_count 是引擎发出 response_received 信号的次数,被重定向、重试中间件消费掉的响应不算。

字节数

实测 · 本机执行输出
  小页面(15 字节):服务器实际收到请求 226 字节;stats downloader/request_bytes = 221
      服务器实际发出响应 92 字节(头 77 + 体 15);stats downloader/response_bytes = 92
  大页面(20,000 字节):服务器实际收到请求 226 字节;stats downloader/request_bytes = 221
      服务器实际发出响应 20077 字节(头 80 + 体 19997);stats downloader/response_bytes = 20077

response_bytes 是线上头加体的字节数;request_bytes 来自请求的合成文本(Host 头不带端口),比线上略短。

自定义统计

实测 · 本机执行输出
  stats 里 mine/* 的键:mine/bytes=1135, mine/last_url=a, mine/max_len=95, mine/min_len=20, mine/pages=3
  回调里 get_value 读到的(最后一次):{'get': 3, 'missing': 'DEFAULT', 'n': 21, 't': 137.2}

crawler.stats 提供 inc_value、set_value、max_value、min_value、get_value、get_stats。

关闭统计

实测 · 本机执行输出
  默认 MemoryStatsCollector:日志里有 “Dumping Scrapy stats”:是;日志里打出的键数 25;spider.closed() 里 crawler.stats.get_stats() 的键数 20
  DummyStatsCollector:日志里有 “Dumping Scrapy stats”:是;日志里打出的键数 0;spider.closed() 里 crawler.stats.get_stats() 的键数 0
  STATS_DUMP=0:日志里有 “Dumping Scrapy stats”:否;日志里打出的键数 0;spider.closed() 里 crawler.stats.get_stats() 的键数 20

STATS_CLASS 换成 DummyStatsCollector 完全不记;STATS_DUMP = 0 只是不在结束时打印。

其它

实测 · 本机执行输出
  DEBUG 级别的运行:log_count/DEBUG=8, log_count/INFO=2, memusage/max=90800128, memusage/startup=90800128
  elapsed_time_seconds 与 finish_time − start_time:0.0091 s  /  0.0091 s

log_count/* 按日志级别计数,memusage/* 来自 MemoryUsage 扩展,elapsed_time_seconds 等于结束时间减开始时间。

分步演示

统计
本步的对象

    本文用到的工具与边界

    • 本机 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,数字每次运行会有小幅抖动。第一节抓取:起始页链接到 /a、/b、/missing(404)、/redir(302 → /a);第二节用原始套接字服务器对照真实字节;并发默认
    • 没有验证:PERIODIC_LOG_STATS 周期性日志;stats 在 CrawlerProcess 多个 crawler 之间是否隔离;STATS_CLASS 自定义实现;大量请求时 MemoryStatsCollector 的内存;memusage 在 Linux 上的取值方式(这里是 macOS);httperror/*、retry/*、robotstxt/* 等专题统计见各自文章
    京ICP备2026067502号-1京公网安备11010502063487号