Stats Collection
Scrapy provides a convenient facility for collecting stats in the form of
key/values, where values are often counters. The facility is called the Stats
Collector, and can be accessed through the stats
attribute of the Crawler API, as illustrated by the examples in
the Common Stats Collector uses section below.
The Stats Collector API is always available, so you can always use it (to increment or set new stat keys), regardless of whether the stats collection is enabled or not. If it’s disabled, the API will still work but it won’t collect anything. This is aimed at simplifying the stats collector usage: you should spend no more than one line of code for collecting stats in your spider, Scrapy extension, or whatever code you’re using the Stats Collector from.
Another feature of the Stats Collector is that it’s very efficient (when enabled) and extremely efficient (almost unnoticeable) when disabled.
See Built-in stats reference below for the stats that Scrapy sets.
Common Stats Collector uses
Access the stats collector through the stats
attribute. Here is an example of an extension that access stats:
class ExtensionThatAccessStats:
def __init__(self, stats):
self.stats = stats
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.stats)
Set stat value:
stats.set_value("hostname", socket.gethostname())
Increment stat value:
stats.inc_value("custom_count")
Set stat value only if greater than previous:
stats.max_value("max_items_scraped", value)
Set stat value only if lower than previous:
stats.min_value("min_free_memory_percent", value)
Get stat value:
>>> stats.get_value("custom_count")
1
Get all stats:
>>> stats.get_stats()
{'custom_count': 1, 'start_time': datetime.datetime(2009, 7, 14, 21, 47, 28, 977139)}
Available Stats Collectors
Besides the basic StatsCollector there are other Stats Collectors
available in Scrapy which extend the basic Stats Collector. You can select
which Stats Collector to use through the STATS_CLASS setting. The
default Stats Collector used is the MemoryStatsCollector.
MemoryStatsCollector
- class scrapy.statscollectors.MemoryStatsCollector(crawler: Crawler)[source]
A simple stats collector that keeps the stats of the last scraping run (for each spider) in memory, after they’re closed. The stats can be accessed through the
spider_statsattribute, which is a dict keyed by spider name.This is the default stats collector used in Scrapy.
DummyStatsCollector
- class scrapy.statscollectors.DummyStatsCollector(crawler: Crawler)[source]
A stats collector which does nothing but is very efficient (because it does nothing). This stats collector can be set via the
STATS_CLASSsetting, to disable stats collection in order to improve performance. However, the performance penalty of stats collection is usually marginal compared to other Scrapy workload like parsing pages.
Built-in stats reference
Scrapy sets the following stats. Components other than those built into Scrapy may set additional stats; see their documentation.
Stat keys that contain a {placeholder} below stand for a family of stats,
one per actual value of the placeholder.
Note
Most stats are set by a specific component, and are only present if that component is enabled and
its code path is reached. A stat that is missing from
get_stats() output is
equivalent to a counter of 0.
depth/request_ignored_countNumber of requests dropped for exceeding
DEPTH_LIMIT.Set by
DepthMiddleware.
downloader/exception_countNumber of exceptions raised while downloading requests.
Set by
DownloaderStats.
downloader/exception_type_count/{exception_type}Number of exceptions raised while downloading requests, per exception type, where
{exception_type}is the import path of the exception class, e.g.twisted.internet.error.DNSLookupError.Set by
DownloaderStats.
downloader/request_bytesTotal size, in bytes, of the requests sent, counting the request line, the headers and the body. As with
downloader/request_count, requests served from the cache are also counted.It is an approximation, reconstructed from each
Requestobject instead of measured on the wire, so it does not account for the actual bytes that the download handler sends, e.g. transport-level overhead.Set by
DownloaderStats.
downloader/request_countNumber of requests sent.
Requests that
HttpCacheMiddlewareserves from the cache are also counted, even though they are never sent, because it handles requests afterDownloaderStats.Set by
DownloaderStats.
downloader/request_method_count/{method}Number of requests sent, per HTTP method, e.g.
GETorPOST. As withdownloader/request_count, requests served from the cache are also counted.Set by
DownloaderStats.
downloader/response_bytesTotal size, in bytes, of the responses received, counting the status line, the headers and the body. It covers the same responses as
downloader/response_count.The body is counted as received, i.e. still compressed for responses that used
Content-Encoding, becauseDownloaderStatshandles responses beforeHttpCompressionMiddlewaredecompresses them. Seehttpcompression/response_bytesfor decompressed sizes.Set by
DownloaderStats.
downloader/response_countNumber of responses received.
It counts responses that
HttpCacheMiddlewareserves from the cache, even though they do not come from the network, and responses that a downloader middleware consumes before they reach your spider, e.g. redirect responses thatRedirectMiddlewareturns into new requests. Compare withresponse_received_count.Set by
DownloaderStats.
downloader/response_status_count/{status_code}Number of responses received, per HTTP status code, e.g.
200or404. It covers the same responses asdownloader/response_count.Set by
DownloaderStats.
dupefilter/filteredNumber of requests dropped as duplicates.
Set by
RFPDupeFilter.
elapsed_time_secondsTime, as a
float, in seconds, between thespider_openedand thespider_closedsignals.Set by
CoreStats.
feedexport/failed_count/{storage}Number of feeds that could not be stored, per storage backend, where
{storage}is the class name of the storage backend, e.g.FileFeedStorage.
feedexport/success_count/{storage}Number of feeds stored successfully, per storage backend, where
{storage}is the class name of the storage backend, e.g.FileFeedStorage.
file_countNumber of files handled by the media pipelines.
file_status_count/{status}Number of files handled by the media pipelines, per status, where
{status}is one of:downloaded: the file was downloaded.cached: the file came from theHttpCacheMiddlewarecache.uptodate: the file was already in the storage backend and had not expired, so it was not downloaded again.
finish_reasonString indicating why the crawl finished. It matches the reason argument of the
spider_closedsignal.Scrapy uses the following reasons:
cancelled: the spider was closed without a more specific reason, e.g. becauseCloseSpiderwas raised without one.closespider_errorcount: seeCLOSESPIDER_ERRORCOUNT.closespider_itemcount: seeCLOSESPIDER_ITEMCOUNT.closespider_pagecount: seeCLOSESPIDER_PAGECOUNT.closespider_pagecount_no_item: seeCLOSESPIDER_PAGECOUNT_NO_ITEM.closespider_timeout: seeCLOSESPIDER_TIMEOUT.closespider_timeout_no_item: seeCLOSESPIDER_TIMEOUT_NO_ITEM.finished: the spider became idle with no pending requests, i.e. it finished normally.memusage_exceeded: seeMEMUSAGE_LIMIT_MB.shutdown: the crawl was interrupted, e.g. by a system signal such asSIGINT(Ctrl-C).start_error:start()raised an exception, so some start requests may never have been sent, see Handling start errors.
Third-party components and your own code may use any other reason, e.g. by raising
CloseSpiderwith it.Set by
CoreStats.
finish_timeTimezone-aware
datetimeobject, in UTC, indicating when thespider_closedsignal was sent.Set by
CoreStats.
httpcache/errorrecoveryNumber of times that a stale cached response was used because downloading a fresh response raised an exception.
Set by
HttpCacheMiddleware.
httpcache/firsthandNumber of responses that were downloaded without a matching cache entry to validate against, i.e. responses for requests counted in
httpcache/miss.It is lower than
httpcache/misswhen some of those requests yield no response, either because they are dropped (seehttpcache/ignore) or because their download fails.Set by
HttpCacheMiddleware.
httpcache/hitNumber of requests served from the cache.
Set by
HttpCacheMiddleware.
httpcache/ignoreNumber of requests dropped because they were not in the cache and
HTTPCACHE_IGNORE_MISSINGisTrue.Set by
HttpCacheMiddleware.
httpcache/invalidateNumber of times that a cached response failed validation and was replaced with a freshly downloaded response.
Set by
HttpCacheMiddleware.
httpcache/missNumber of requests for which no cache entry could be read, either because there was none or because reading it failed, in which case the request is also counted in
httpcache/retrieve_error. Those requests are downloaded (seehttpcache/firsthand), or dropped ifHTTPCACHE_IGNORE_MISSINGisTrue(seehttpcache/ignore).Requests with a stale cache entry are not counted here; see
httpcache/revalidateandhttpcache/invalidate.Set by
HttpCacheMiddleware.
httpcache/retrieve_errorNumber of cache entries that could not be read, and hence were treated as cache misses. Those requests are also counted in
httpcache/miss.Set by
HttpCacheMiddleware.
httpcache/revalidateNumber of times that a cached response was successfully validated against the target server, and hence used instead of the fresh response.
Set by
HttpCacheMiddleware.
httpcache/storeNumber of responses stored in the cache.
Set by
HttpCacheMiddleware.
httpcache/uncacheableNumber of responses not stored in the cache because the
HTTPCACHE_POLICYdid not allow it.Every response considered for caching is counted either here or in
httpcache/store, sohttpcache/store + httpcache/uncacheableequalshttpcache/firsthand + httpcache/invalidate.Set by
HttpCacheMiddleware.
httpcompression/response_bytesTotal size, in bytes, of decompressed response bodies, counting only the body and only responses that were actually decompressed. Compare with
downloader/response_bytes.Set by
HttpCompressionMiddleware.
httpcompression/response_countNumber of decompressed responses.
Set by
HttpCompressionMiddleware.
httperror/response_ignored_countNumber of responses dropped because of their HTTP status code.
Set by
HttpErrorMiddleware.
httperror/response_ignored_status_count/{status_code}Number of responses dropped because of their HTTP status code, per HTTP status code, e.g.
404.Set by
HttpErrorMiddleware.
item_dropped_countNumber of items dropped by an item pipeline, i.e. number of times that the
item_droppedsignal was sent.Set by
CoreStats.
item_dropped_reasons_count/{exception}Number of items dropped, per exception, where
{exception}is the class name of the exception that caused the item to be dropped.Only
DropItemand its subclasses drop items, and each one is counted under its own class name, e.g.item_dropped_reasons_count/DropItemforDropItemitself anditem_dropped_reasons_count/MyDropItemfor aMyDropItemsubclass of it. Any other exception raised by an item pipeline triggers theitem_errorsignal instead ofitem_dropped, and is not counted here or initem_dropped_count.Set by
CoreStats.
item_scraped_countNumber of items that passed all item pipelines, i.e. number of times that the
item_scrapedsignal was sent.Set by
CoreStats.
items_per_minuteAverage number of items scraped per minute during the crawl.
It is
Noneif the crawl took less than a minute.Set by
LogStats.
log_count/{level}Number of log messages, per logging level name, e.g.
INFOorWARNING.Only messages that the
LOG_LEVELsetting allows are counted.Set by
LogCount.
memdebug/gc_garbage_countNumber of objects in
gc.garbagewhen the spider is closed.Set by
MemoryDebugger, which requiresMEMDEBUG_ENABLEDto beTrue.
memdebug/live_refs/{cls}Number of live objects of class
{cls}when the spider is closed, as reported by trackref, e.g.memdebug/live_refs/HtmlResponse.Only set for classes with at least 1 live object.
Set by
MemoryDebugger, which requiresMEMDEBUG_ENABLEDto beTrue.
memusage/limit_reached1if memory usage exceededMEMUSAGE_LIMIT_MB, which also stops the crawl.Set by
MemoryUsage.
memusage/maxMaximum peak memory usage, in bytes, observed during the crawl.
Set by
MemoryUsage.
memusage/startupPeak memory usage, in bytes, when the engine started.
Set by
MemoryUsage.
memusage/warning_reached1if memory usage exceededMEMUSAGE_WARNING_MB.Set by
MemoryUsage.
offsite/domainsNumber of distinct domains for which at least 1 request was dropped for being offsite.
Set by
OffsiteMiddleware.
offsite/filteredNumber of requests dropped for being offsite.
Set by
OffsiteMiddleware.
request_depth_count/{depth}Number of requests scheduled at depth
{depth}, e.g.request_depth_count/2.Set by
DepthMiddleware, which requiresDEPTH_STATS_VERBOSEto beTruefor this stat.
request_depth_maxMaximum depth reached.
Set by
DepthMiddleware.
response_received_countNumber of responses received, i.e. number of times that the
response_receivedsignal was sent.Unlike
downloader/response_count, it does not count responses that a downloader middleware consumes before they reach the engine, e.g. redirect responses thatRedirectMiddlewareturns into new requests. Both count responses thatHttpCacheMiddlewareserves from the cache.Set by
CoreStats.
responses_per_minuteAverage number of responses received per minute during the crawl.
It is
Noneif the crawl took less than a minute.Set by
LogStats.
retry/countNumber of requests retried.
Set by
get_retry_request(), whichRetryMiddlewareuses.
retry/max_reachedNumber of requests that were not retried because they had already been retried
RETRY_TIMEStimes.Set by
get_retry_request(), whichRetryMiddlewareuses.
retry/reason_count/{reason}Number of requests retried, per reason, e.g.
retry/reason_count/twisted.internet.error.TimeoutErrororretry/reason_count/504 Gateway Time-out.Set by
get_retry_request(), whichRetryMiddlewareuses.
Note
Code calling
get_retry_request() may pass a
custom stats_base_key, in which case retry is replaced with that key
in the 3 stats above.
robotstxt/exception_count/{exception_type}Number of exceptions raised while downloading
robots.txtfiles, per exception type, where{exception_type}is the string representation of the exception class, e.g.<class 'twisted.internet.error.DNSLookupError'>.Set by
RobotsTxtMiddleware.
robotstxt/forbiddenNumber of requests dropped for being disallowed by
robots.txt.Set by
RobotsTxtMiddleware.
robotstxt/request_countNumber of
robots.txtfiles requested, i.e. 1 per network location for which at least 1 request was sent.Set by
RobotsTxtMiddleware.
robotstxt/response_countNumber of
robots.txtresponses received.Set by
RobotsTxtMiddleware.
robotstxt/response_status_count/{status_code}Number of
robots.txtresponses received, per HTTP status code, e.g.404.Set by
RobotsTxtMiddleware.
scheduler/dequeuedNumber of requests read from the scheduler.
scheduler/dequeued/diskNumber of requests read from the disk queue of the scheduler.
scheduler/dequeued/memoryNumber of requests read from the memory queue of the scheduler.
scheduler/enqueuedNumber of requests stored into the scheduler.
scheduler/enqueued/diskNumber of requests stored into the disk queue of the scheduler.
scheduler/enqueued/memoryNumber of requests stored into the memory queue of the scheduler.
scheduler/unserializableNumber of requests that could not be stored into the disk queue of the scheduler because they could not be serialized, and hence were stored into the memory queue instead.
spider_exceptions/countNumber of unhandled exceptions raised by spider callbacks or by
start().
spider_exceptions/{exception}Same as
spider_exceptions/count, per exception, where{exception}is the class name of the exception, e.g.spider_exceptions/ValueError.
start_timeTimezone-aware
datetimeobject, in UTC, indicating when thespider_openedsignal was sent.Set by
CoreStats.
urllength/request_ignored_countNumber of requests dropped for having a URL longer than
URLLENGTH_LIMIT.Set by
UrlLengthMiddleware.