Splash 是一个 JavaScript 渲染服务,是一个带有 HTTP API 的轻量级浏览器,同时它对接了 Python 中的 Twisted 和 QT 库。利用它,我们同样可以实现动态渲染页面的抓取。
Splash在Github上源码:https://github.com/scrapinghub/splash
Splash官网文档:Splash - A javascript rendering service — Splash 3.5 documentation
一、Splash简介安装
(一)功能介绍
利用 Splash 我们可以实现如下功能:
- 异步方式处理多个网页渲染过程
- 获取渲染后的页面的源代码或截图
- 通过关闭图片渲染或者使用 Adblock 规则来加快页面渲染速度
- 可执行特定的 JavaScript 脚本
- 可通过 Lua 脚本来控制页面渲染过程
- 获取渲染的详细过程并通过 HAR(HTTP Archive)格式呈现
(二)scrapy_splash
scrapy_splash是scrapy的一个组件,scrapy-splash加载js数据是基于Splash来实现的
(三)安装运行Splash
1、安装Docker:如果还没有安装Docker,需要先安装Docker。Docker是一种容器化技术,可以让应用程序在一个轻量级的虚拟化环境中运行。可以在Docker的官方网站上找到适合操作系统的安装指南。
2、拉取Splash镜像:在终端中运行以下命令来下载Splash的Docker镜像:
docker pull scrapinghub/splash
另外,还可以把容器内的目录映射到本地,这样保证了数据的持久化,否则下次启动一个新的容器配置都变了,容器内有四个主要目录:
- /etc/splash/filters:存放过滤器的文件夹
- /etc/splash/proxy-profiles:存放代理配置的文件夹
- /etc/splash/js-profiles:存放js脚本的文件夹
- /etc/splash/lua_modules:存放lua脚本的文件夹
映射到本地的命令是(-v就表示映射文件夹),其他类似:
docker run -p 8050:8050 -v 本地绝对路径:/etc/splash/filters scrapinghub/splash
3、运行Splash容器:下载完成后,运行以下命令启动Splash
docker run -p 8050:8050 scrapinghub/splash
- `-d`:后台运行容器。
- `-p 8050:8050`:将容器端口 8050 映射到本地 8050 端口
这将启动Splash服务,并在本地主机的8050端口上运行。
在python虚拟环境中安装scrapy-splash包
pip install scrapy-splash
4、验证Splash安装:访问 "http://localhost:8050",若看到 Splash 管理界面,则安装成功。
FAQs:
1、解决获取镜像超时:修改docker的镜像源
1、创建并编辑docker的配置文件
sudo vi /etc/docker/daemon.json
2、 国内http://docker-cn.com的镜像地址配置后保存退出
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
或者配置配置阿里源镜像加速器:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台
将阿里云中的加速器地址配置下来
"registry-mirrors": [
"https://(登陆之后自己替换).mirror.aliyuncs.com",
"https://registry.docker-cn.com"
]
- 重启电脑或docker服务后重新获取splash镜像
- 这时如果还慢,请使用手机热点(流量orz)
二、Splash使用
1、修改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
import scrapy
class NoSplashSpider(scrapy.Spider):
name = 'no_splash'
allowed_domains = ['baidu.com']
start_urls = ['https://www.baidu.com/s?wd=18161922208']
def parse(self, response):
with open('no_splash.html', 'w') as f:
f.write(response.body.decode())
#使用splash
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=18161922208']
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())
Splash 与 Selenium 对比
参考文章链接:
python Splash如何启动_mob64ca12f1c6f8的技术博客_51CTO博客