1. 简介
1.1 定义
scrapy_splash
是scrapy
的一个组件scrapy-splash
加载js
数据是基于Splash
来实现的。Splash
是一个Javascript
渲染服务。它是一个实现了HTTP API
的轻量级浏览器,Splash
是用Python
和Lua
语言实现的,基于Twisted
和QT
等模块构建。- 使用
scrapy-splash
最终拿到的response
相当于是在浏览器全部渲染完成以后的网页源代码
1.2 作用
scrapy-splash
能够模拟浏览器加载js
,并返回js
运行后的数据,获取渲染的网页
1.3 文档
- splash官方文档 :https://splash.readthedocs.io/en/stable/
- 关于splash :https://www.cnblogs.com/zhangxinqi/p/9279014.html
2. 使用
- 修改
docker
的镜像源,加快获取镜像
- 创建并编辑docker的配置文件
sudo vi /etc/docker/daemon.json
- 写入国内docker-cn.com的镜像地址配置后保存退出
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
- 重启电脑或
docker
服务后重新获取splash
镜像
- 在正确安装
docker
的基础上pull
取splash
的镜像
sudo docker pull scrapinghub/splash
- 验证是否安装成功
-
运行
splash
的docker
服务,并通过浏览器访问8050
端口验证安装是否成功 -
前台运行
sudo docker run -p 8050:8050 scrapinghub/splash
- 后台运行
sudo docker run -d -p 8050:8050 scrapinghub/splash
- 访问
http://127.0.0.1:8050
看到如下截图内容则表示成功
- 关闭
splash
服务
- 需要先关闭容器后,再删除容器
sudo docker ps -a
sudo docker stop CONTAINER_ID
sudo docker rm CONTAINER_ID
- 在
python
虚拟环境中安装scrapy-splash
包
pip install scrapy-splash
- 安装并启动
docker
服务参考文档:https://blog.csdn.net/sanpic/article/details/81984683 splash
官方文档安装相应的依赖环境:https://github.com/scrapinghub/splash/blob/master/Dockerfile
3. 应用
需求:以某度为例
步骤:
- 创建项目创建爬虫
scrapy startproject test_splash
cd test_splash
scrapy genspider no_splash baidu.com
scrapy genspider with_splash baidu.com
- 完善
settings.py
配置文件
- 在
settings.py
文件中添加splash
的配置以及修改robots
协议
# 渲染服务的url
SPLASH_URL = 'http://127.0.0.1:8050'
# 下载器中间件
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
# 去重过滤器
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
# 使用Splash的Http缓存
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
- 不使用
splash
- 在
spiders/no_splash.py
中完善
import scrapy
class NoSplashSpider(scrapy.Spider):
name = 'no_splash'
allowed_domains = ['baidu.com']
start_urls = ['https://www.baidu.com/s?wd=13161933309']
def parse(self, response):
with open('no_splash.html', 'w') as f:
f.write(response.body.decode())
- 使用
splash
- 在
spiders/with_splash.py
中完善
import scrapy
from scrapy_splash import SplashRequest # 使用scrapy_splash包提供的request对象
class WithSplashSpider(scrapy.Spider):
name = 'with_splash'
allowed_domains = ['baidu.com']
start_urls = ['https://www.baidu.com/s?wd=13161933309']
def start_requests(self):
yield SplashRequest(self.start_urls[0],
callback=self.parse_splash,
args={'wait': 10}, # 最大超时时间,单位:秒
endpoint='render.html') # 使用splash服务的固定参数
def parse_splash(self, response):
with open('with_splash.html', 'w') as f:
f.write(response.body.decode())
- 运行
- 分别运行俩个爬虫
scrapy crawl no_splash
scrapy crawl with_splash
-
观察获取的俩个html文件
-
不使用
splash
- 使用
splash
3. 结论
- splash类似selenium,能够像浏览器一样访问请求对象中的url地址
- 能够按照该url对应的响应内容依次发送请求
- 并将多次请求对应的多次响应内容进行渲染
- 最终返回渲染后的response响应对象