Scrapy结合Splash爬取JS页面无返回结果问题求助
结合你描述的情况——普通HTML爬虫正常,Splash相关的爬虫无输出,修改Telnet端口报错,我从几个核心环节帮你一步步排查:
1. 先确认Splash服务是否真的在正常运行
这是最基础但最容易忽略的一步:
- 打开终端运行
docker ps,检查scrapinghub/splash容器是否处于Up状态,如果显示Exited,说明容器启动失败,你可以用docker logs <容器ID>查看报错原因,比如端口被占用、资源不足等。 - 直接在浏览器访问
http://localhost:8050,如果能看到Splash的Web测试界面,说明服务正常;如果打不开,要么容器没启动,要么端口映射有问题。
2. 检查Scrapy项目的Splash配置是否完整
确保你的settings.py里已经正确配置了Splash相关的中间件和参数,顺序和内容缺一不可:
# 指向本地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, } # 去重过滤器要换成Splash兼容的 DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
另外你提到修改Telnet端口报错——Splash的5023端口是它自身的Telnet服务,而Scrapy默认也会启用Telnet服务(默认端口6023),与其修改Splash的映射端口,不如直接调整Scrapy的配置来规避冲突:
# 在settings.py里添加,把Scrapy的Telnet端口改成别的 TELNET_PORT = 6024 # 或者干脆关闭Scrapy的Telnet服务(如果不需要的话) TELNETCONSOLE_ENABLED = False
3. 检查爬虫代码是否正确使用了SplashRequest
很多新手会犯的错误:用了普通的scrapy.Request而不是SplashRequest,这样根本没用到Splash的JS渲染服务。正确的示例代码应该是:
import scrapy from scrapy_splash import SplashRequest class JSDemoSpider(scrapy.Spider): name = 'jsdemo' allowed_domains = ['你的目标域名'] start_urls = ['你的目标JS页面URL'] def start_requests(self): # 用SplashRequest替代Request,添加渲染参数 yield SplashRequest( url=self.start_urls[0], callback=self.parse, args={ 'wait': 2, # 等待JS渲染的时间,根据页面复杂度调整,太短可能渲染不完整 'render_all': 1, # 渲染整个页面(包括动态加载内容) } ) def parse(self, response): # 先打印基础信息确认是否获取到渲染后的页面 self.logger.info(f"响应状态码:{response.status}") self.logger.info(f"页面内容长度:{len(response.text)}") # 你的内容提取逻辑...
如果打印的内容长度很小,大概率是渲染时间不够,调大wait参数(比如改成3、5)再试试。
4. 查看详细日志定位问题
运行爬虫时加上日志参数,方便深挖细节:
scrapy crawl jsdemo --logfile scrapy.log --loglevel DEBUG
然后打开scrapy.log,搜索这些关键词:
Splash:看是否有请求发送到Splash的记录,URL是否正确response:检查响应状态码,200是正常,404是页面不存在,500是Splash内部错误error:有没有连接超时、中间件加载失败等报错信息
5. 排查端口冲突问题
Mac上可以用lsof -i :8050和lsof -i :5023检查端口是否被其他程序占用,如果被占用,要么停止占用的程序,要么修改Docker的端口映射:
# 把Splash的8050映射到本地8051,5023映射到本地5024 docker run -p 8051:8050 -p 5024:5023 scrapinghub/splash
同时记得修改settings.py里的SPLASH_URL为http://localhost:8051。
最后确认依赖包是否兼容
在你的Python3.6.4虚拟环境里,运行pip list确认scrapy和scrapy-splash都已安装,且版本兼容——Python3.6对应的scrapy-splash建议用0.7.2版本,可以用pip install scrapy-splash==0.7.2指定安装。
按照上面的步骤一步步排查,应该能找到问题所在!
内容的提问来源于stack exchange,提问作者goblin_rocket

