You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scrapy CrawlSpider多进程运行内存泄漏致服务器崩溃排查求助

Scrapy CrawlSpider内存泄漏排查解决方法

核心问题定位

你观测到Python层对象总大小仅数MB但内存占满,说明泄漏发生在C扩展层,结合你换基础Spider无问题的现象,问题出在CrawlSpider依赖的lxml解析缓存、规则编译缓存两个方向。

修复步骤

1. 修正代码不规范写法

你当前的两处写法直接导致内存累积:

  • rules属性必须定义为类属性:你将rules放在__init__内作为实例属性赋值,CrawlSpider初始化时会重复编译规则,产生的lxml XPath编译缓存不会被Python GC回收,属于C层内存泄漏。
  • XPath写法低效触发缓存累积:你写的//a[not(//footer)]每次匹配节点时都会全局扫描文档生成footer节点集,lxml的临时节点对象在C层累积,不会被Python内存统计工具检测到。

修正后的代码如下:

from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor

class wb8(CrawlSpider):
    name = 'wb8'
    # rules移至类属性,拆分规则实现需求
    rules = (
        # 规则1:匹配footer内的链接,优先级高
        Rule(
            LinkExtractor(restrict_xpaths="//footer//a", unique=True),
            callback='parse_test',
            follow=True
        ),
        # 规则2:如果没有匹配到footer链接,自动走全页a提取,fallback逻辑
        Rule(
            LinkExtractor(tags=('a',), unique=True),
            callback='parse_test',
            follow=True,
            process_links=lambda links: links if not any('footer' in l.url for l in links) else []
        )
    )

    def __init__(self, bdd_id, domain, cleaned_domain, *a, **kw):
        self.domain = domain
        self.bdd_id = bdd_id
        self.start_urls = [domain]
        self.allowed_domains = [cleaned_domain]
        super().__init__(*a,**kw)

    def parse_start_url(self, response):
        return self.parse_test(response)

    def parse_test(self,response):
        # 处理完响应后手动删除引用,触发GC回收
        res = response.text[:100] # 按需处理响应内容
        del response
        yield {}

2. 添加Scrapy配置优化

在settings.py加入以下配置,切断缓存累积路径:

# 关闭不必要的缓存
COOKIES_ENABLED = False
DOWNLOADER_STATS = False
# 限制并发数,避免同时存在过多lxml解析对象
CONCURRENT_REQUESTS = 16
# 开启响应自动回收
RESPONSE_PAYLOAD_SIZE_LIMIT = 10*1024*1024 # 限制单响应最大10MB

3. 多进程场景额外处理

如果是多进程循环启动爬虫实例,每次实例运行结束后添加以下代码手动释放C层缓存:

import gc
import lxml.etree
# 释放lxml全局缓存
lxml.etree.cleanup_namespaces()
lxml.etree.clear_error_log()
# 强制Python GC回收
gc.collect()

内容的提问来源于stack exchange,提问作者IndiaSke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:48:00