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
相关产品推荐
相关产品推荐

