Scrapy-Splash循环提交表单无响应,回调未触发问题求助
解决Scrapy-Splash循环请求无回调的问题
核心问题:Scrapy默认URL去重拦截了后续请求
Scrapy默认启用了请求去重机制,当你循环发送相同URL的SplashRequest时,除了第一个请求,剩下的都会被判定为重复请求而被过滤,根本不会实际发送到Splash服务。这就是为什么你的parse2只被调用一次、全局变量c只打印一次的核心原因。
修复方案
1. 给循环中的SplashRequest添加dont_filter=True
在yield SplashRequest时加上这个参数,明确告诉Scrapy不要对当前请求进行去重:
yield SplashRequest( url=self.start_urls[0], callback=self.parse2, endpoint='execute', args={'wait': 10, 'timeout':60, 'lua_source': src}, cache_args=['lua_source'], dont_filter=True # 关键:关闭当前请求的去重逻辑 )
2. 确保Lua脚本的上下文独立性
要避免前一次请求的页面状态影响后续执行,你的Lua脚本应该每次都重新加载目标页面,而不是依赖Scrapy传入的上下文。比如在脚本开头显式触发页面访问:
function main(splash, args) splash:go(args.url) -- 确保每次执行都重新加载页面 splash:wait(args.wait) -- 你的表单填充、提交逻辑 -- ... return splash:html() end
这样可以避免第一次提交后页面跳转或状态残留,导致后续脚本无法正常交互。
3. 替换全局变量(可选但更安全)
全局变量c在Scrapy的多线程环境下可能出现竞态问题,建议用response.meta传递计数,更稳妥:
for idx, field in enumerate(fields[0:10]): try: src = self.LUA_SOURCE % (field) print(src) yield SplashRequest( url=self.start_urls[0], callback=self.parse2, endpoint='execute', args={'wait': 10, 'timeout':60, 'lua_source': src}, cache_args=['lua_source'], dont_filter=True, meta={'file_idx': idx+1} # 把索引传递到回调函数 ) except Exception as e: print(e) def parse2(self, response): file_idx = response.meta['file_idx'] try: with open(f'text_files/{file_idx}.txt', 'w') as f: f.write(response.text) except Exception as e: print(e)
4. 检查cache_args的合理性
如果你的lua_source每次循环都会因为field替换生成不同内容,那么cache_args=['lua_source']其实没有意义——这个参数是用来缓存固定不变的Lua脚本以减少传输量。如果每次脚本都不同,建议移除这个参数,避免Splash缓存旧的脚本内容。
验证步骤
- 添加
dont_filter=True后运行爬虫,观察c(或文件索引)是否从1递增到10 - 检查Scrapy的DEBUG日志(设置
LOG_LEVEL='DEBUG'),确认10个请求都被正常发送 - 验证每个生成的txt文件内容是否对应不同
field的提交结果
内容的提问来源于stack exchange,提问作者steveMcain
相关产品推荐
相关产品推荐

