Scrapy 性能优化该调哪些参数?并发、限速和 Pipeline 怎么取舍?
先说结论
Scrapy 性能优化不是把并发调到最大,而是在目标站承受能力、网络延迟、本机资源、代理质量和数据写入速度之间找平衡。真正影响吞吐的通常有四块:下载并发、延迟与自动限速、重复请求与缓存、解析和 Pipeline 的耗时。只盯 CONCURRENT_REQUESTS 很容易误判,爬虫跑不快可能不是请求少,而是 DNS、代理、数据库写入或解析逻辑卡住了。
可以先用一组保守配置跑基准,再逐步调高:
pythonCONCURRENT_REQUESTS = 32 CONCURRENT_REQUESTS_PER_DOMAIN = 8 DOWNLOAD_DELAY = 0.2 RANDOMIZE_DOWNLOAD_DELAY = True AUTOTHROTTLE_ENABLED = True AUTOTHROTTLE_START_DELAY = 0.5 AUTOTHROTTLE_MAX_DELAY = 10 AUTOTHROTTLE_TARGET_CONCURRENCY = 2.0 RETRY_TIMES = 2 HTTPCACHE_ENABLED = False
命令上可以用 scrapy crawl spider -s LOG_LEVEL=INFO 看整体速度,用 scrapy bench 做框架基准,但不要把 bench 结果当成线上能力。真实站点会有限速、验证码、慢接口和异常页面,性能优化必须结合日志和 stats 看。
并发不是越高越好
Scrapy 基于 Twisted 异步网络模型,单进程就能同时处理多个请求。提高并发能减少等待时间,但目标站响应变慢、403 增多、代理超时上升时,再加并发只会让失败更快发生。经验上先看 downloader/response_status_count/200、retry/count、download_latency,确认瓶颈是不是网络请求。
如果一个域名很慢,可以调 CONCURRENT_REQUESTS_PER_DOMAIN;如果同时抓多个站,才更需要关注全局 CONCURRENT_REQUESTS。边界是本机 CPU、内存、文件句柄和代理池也会被并发放大,尤其是页面解析里用了复杂 XPath、正则或大对象暂存时。
AutoThrottle 和下载延迟怎么配
DOWNLOAD_DELAY 是固定刹车,简单可靠,适合目标站规则明确的场景。AutoThrottle 会根据延迟动态调整速度,更适合响应波动大的站点。取舍是 AutoThrottle 不等于反爬万能药,它主要基于响应延迟判断,不理解验证码、业务封禁和账号风控。
如果站点对请求频率敏感,宁愿慢一点,也不要追求短时间峰值。稳定跑完比十分钟冲高后被封一整天更值钱。
Pipeline 和存储经常是隐藏瓶颈
很多爬虫下载很快,最后慢在 Pipeline。每条 item 都同步查库、逐条提交、上传图片或调用外部接口,都会堵住处理链路。更好的方式是批量写入、异步队列、连接池,或者先落 JSON Lines,再由离线任务清洗入库。
这里的边界是可靠性。批量越大,吞吐越好,但失败回滚和重复写入处理越复杂;批量太小,又浪费数据库往返。实际项目里通常会用唯一键去重,再把批量大小控制在数据库能稳定承受的范围内。
缓存、去重和请求优先级
开发阶段打开 HTTP cache 能减少重复请求,调选择器时很省时间。生产采集是否开启要看数据时效性,如果价格、库存、状态变化很快,缓存会让结果过期。请求优先级适合详情页、补采任务和失败重试排序,但不要把调度器当业务队列用,复杂优先级最好在任务生成阶段处理。
追问
并发调高后速度没变,应该先查什么?
先看下载延迟、重试数量和状态码分布,而不是继续加并发。如果 download_latency 很高或 429、403 增多,说明目标站或代理已经在限制你。再看 Pipeline 是否耗时,尤其是数据库写入和外部 API 调用。只有确认请求链路仍有空闲,继续提高并发才有意义。
AutoThrottle 会不会影响抓取效率?
会,它本来就是用部分速度换稳定性。目标站响应慢时它会主动降速,短期看吞吐下降,长期看可能减少封禁和重试。边界是它只能根据延迟做判断,遇到验证码页返回很快时可能误判为站点很健康。重要任务最好同时监控异常状态码和页面内容。
Pipeline 如何优化才不丢数据?
不要一上来就把所有写入都改成异步而不做失败处理。可以先把原始 item 落到 JSON Lines,再批量入库,这样数据库挂了还有恢复来源。批量写入要配唯一键或幂等逻辑,否则重跑任务会产生重复数据。取舍是链路变长了,但排查和恢复能力会强很多。
Scrapy 缓存适合线上开启吗?
开发和调试阶段很适合,线上要谨慎。新闻、价格、库存这类强时效数据不适合长期缓存,否则你优化的是速度,损失的是准确性。文档页、分类页、结构稳定的页面可以短期缓存,减少重复下载。边界要写清楚,比如缓存过期时间和哪些请求不允许缓存。
什么时候需要多进程或分布式?
单机 Scrapy 的瓶颈通常先出现在目标站限制、代理质量或存储链路,而不是框架本身。只有单进程资源吃满、任务量大到单机跑不完,或需要多机器协作时,才考虑 scrapyd、队列或分布式调度。分布式会带来去重、状态一致性、任务切分和监控成本。小任务硬上分布式,最后往往是运维复杂度大于性能收益。