scrapy_splash批量请求URL时无法返回完整渲染HTML问题求助
问题排查与解决方案
- 第一个问题:无效的请求间隔控制
你在start_requests里加的time.sleep(10)完全不生效,scrapy是异步框架,生成请求阶段的sleep只会延迟请求的创建时间,不会控制请求发送到Splash的间隔,多个请求会同时发到Splash服务,超过Splash的处理能力就会返回未完全渲染的内容。
解决方法:在项目settings.py中添加如下配置,强制单次只发送一个请求到Splash,和你单独测试单URL的场景完全一致:CONCURRENT_REQUESTS = 1 DOWNLOAD_DELAY = 5 SPLASH_CONCURRENT_REQUESTS = 1 - 第二个问题:Lua脚本缺少会话重置配置
你实际调用的wait_script没有关闭私有模式,也没有清理上下文缓存,多请求时Splash会复用前一个请求的会话上下文,可能触发目标网站的反爬限制或者缓存异常,导致页面渲染不全。同时固定等待10秒的逻辑不可靠,网络波动时可能10秒还没加载完目标元素,修改后的Lua脚本如下:wait_script = """ function main(splash, args) splash.private_mode_enabled = false splash.images_enabled = false assert(splash:go(args.url)) -- 改为等待目标元素出现再返回,最多等15秒,比固定等待兼容性更强 splash:wait_for_resume([[ function check() { if (document.querySelector('div.ec-table__cell-content')) { window.splash_resume(true); } else { setTimeout(check, 500); } } check(); ]], 15) return { html = splash:html(), } end """ - 第三个问题:解析逻辑缺少异常兼容
页面渲染失败时value会返回None,直接调用re.search会抛出异常,建议在解析逻辑里增加判空处理:def scrape_document_id(self, response): value = response.xpath('//div[@class="ec-table__cell-content ng-binding ng-scope" and text() = "Rapport annuel"]/../..//td/ec-button/@mstar-component-id').get() if not value: self.logger.error(f"未找到目标元素,url: {response.url}") return print("VALUE", value) v = re.search(r"\[([^]]+)\]", value).group().strip("[]") yield { "url": response.url, "id" : v } - 可选优化:如果是Docker部署的Splash服务,多请求渲染不全也可能是内存不足导致的,可以在启动Splash时调大内存限制:
docker run -it -p 8050:8050 --memory=4g scrapinghub/splash
内容的提问来源于stack exchange,提问作者Pyd
相关产品推荐
相关产品推荐

