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

Scrapy+Splash单页爬取极慢超时问题求助

Scrapy+Splash爬取超时问题排查与提速方案

一、核心问题分析

测试站(quotes.toscrape.com)无JS渲染需求,Splash处理快;加拿大税局页面是动态渲染页面,但300秒仍超时,大概率是Splash渲染配置不合理或目标网站反爬限制,也可能是你的Scrapy-Splash参数设置有误。

二、配置与代码排查要点

1. Splash服务与中间件检查

先确认Splash服务正常运行(直接访问http://localhost:8050能看到Splash页面就没问题),然后检查settings.py里的配置是否正确:

# Splash核心配置
SPLASH_URL = 'http://localhost:8050'
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
SPIDER_MIDDLEWARES = {
    'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

注意中间件顺序不能乱,SplashMiddleware必须在HttpCompressionMiddleware之前。

2. 请求参数优化

你的SplashRequest可能没设置合理的渲染参数,导致渲染耗时过长。试试调整成这样:

yield SplashRequest(
    url='https://www.canada.ca/en/revenue-agency/services/forms-publications/forms.html',
    callback=self.parse,
    args={
        'wait': 2,  # 动态内容加载完成就够,别设太长,2-5秒足够
        'render_all': False,  # 只渲染可见区域,减少DOM节点处理量
        'js_source': "document.querySelectorAll('script').forEach(s => s.remove());",  # 移除所有script标签
        'html': 1,  # 只返回HTML,不要额外资源
        'timeout': 60,  # Splash自身超时,别超过Scrapy的下载超时
    },
    download_timeout=60,  # Scrapy下载超时设60秒足够,300秒太长容易触发反爬
)
  • wait设太高纯浪费时间,多数动态页面2秒内就能加载完
  • render_all=False能大幅减少Splash的渲染工作量
  • 通过js_source注入JS删掉script标签,直接缩小返回的HTML体积

3. 反爬规避检查

加拿大税局这类政府网站有反爬机制,得做基础的伪装:

  • 配置真实的User-Agent:
DEFAULT_REQUEST_HEADERS = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
}
  • 添加请求延迟,避免频繁请求:
DOWNLOAD_DELAY = 2

三、提速关键措施

  • 跳过Splash直接爬API:如果能找到页面动态加载的API接口,直接用Scrapy普通Request请求API,速度比Splash快10倍以上
  • 限制返回内容:除了移除script标签,还可以用JS删掉style、iframe等不需要的元素,进一步缩小HTML
  • 复用Splash会话:给SplashRequest加session_id参数,复用浏览器会话,避免每次请求重新初始化:
yield SplashRequest(
    url=url,
    callback=self.parse,
    args={'wait': 2},
    session_id='my_fixed_session'
)
  • 升级Splash性能:如果是用Docker跑Splash,默认内存可能不够,启动时加内存限制:
docker run -d -p 8050:8050 --memory=4g scrapinghub/splash

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:57:46