前言
本文主要介绍scrapy-splash的理论知识。文中如有不正确的地方望大家指正。
本文的主要内容出自书:《精通Scrapy网络爬虫》《虫术——Python绝技》
背景
近几年随着前端技术和手机端App的飞速发展,互联网架构也发生了巨大的变化,尤其是一些前端框架的大面积应用,过去基于纯后端的Web结构已经明显过时了。越来越多的网站采用前后端分离的架构。
所谓前后端分离,就是指一个网站由前端和后端两拔人独立开发,相互之间只通过JSON作为通信接口,从开发到部署几乎没有交集。这样的网站对于掉来说 无疑是一种灾难,因为脚本化的网页如果没有脚本引擎在客户端进行二次解释执行,是不能还原成它们“真正”的样子的。在开发者模式下往往会发现,打开一个网页时通常会下载N多个用于渲染的网页。
Scrapy只能处理一些非常简单的AJAX请求,但是这对于复杂的前端页面往往是不够的。要在Python中处理Javascript网页有两种办法:
- Selenium + WebDriver
- Splash
Splash安装
pip3 install scrapy-splash
- docker环境
要正常的使用scrapy-splash,还需要安装docker,然后在docker环境下运行splash。
总体来说docker有两个版本,一个是专门为win10企业版开发的,另一个则是各windows支持的docker toolbox。而我使用的则是docker toolbox。docker安 装好以后会有下面的三个图标:
点击最右边的图标则会进入docker,第一使用时配置的时间可以会比较长。成功后是这样的:
进入该界面后,可以先搜索splash。命令:
docker search splash
可以看到这里列出了好多splash镜像,这里我们选择第一个。通过命令:
docker pull scrapinghub/splash
因为这里我的镜像已经拉取完毕,所以不再给出图片。
拉取镜像的过程可能会比较慢,建议可以去申请一个docker加速器(免费的)(https://www.daocloud.io/mirror), 配置好后下载速度会有提升。
Splash使用
安装好后则可以启动docker上的splash。命令:
docker run -p 8050:8050 scrapinghub/splash
这时打开浏览器,输入192.168.99.100:8050,可以看到这样的页面:
此时,splash可以正常使用。
程序相关
setting中的配置项有:
SPLASH_URL = 'http://192.168.99.100:8050'
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
DOWNLOADER_MIDDLEWARES = {
'scrapy_splash.SplashCookiesMiddleware':723,
'scrapy_splash.SplashMiddleware':725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware':810,
}
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware':100,
}
spiders中的使用
由之前的scrapy.request
换成了scrapy_splash.SplashRequest()
- Splash的请求对象
最简单的渲染请求的方式是使用scrapy_splash.SplashRequest
,通常应该选择使用yield SplashRequest:
yield SplashRequest(url,self.parse_resutl,
args={
#此字典为向Splash HTTP API传送的可选参数;
'wait':0.5,
#'url'每个请求预告填充的目标请求地址
#'http_method'用于设置请求方法,如POST、PUT
#'body'设置用于POST方法时向服务端发起的请求正文
},
endpoint='render.json', #可选;默认为render.html即JS页面渲染服务
splash_url='<url>', #可选,用于覆盖配置文件中的SPLASH_URL选项
slot_policy=scrapy_splash.SlotPolicy.RER_DOMAIN, #可选
)
另外,还可以在普通的Scrapy请求中传递Splash请求meta关键字以实现同样的效果。
yield scrapy.Request(url,self.parse_result,meta={
'splash':{
'args':{
'html':1,
'png':1
'wait':0.5,
},
endpoint='render.json',
splash_url='<url>',
'slot_policy':'scrapy_splash.SlotPolicy.RER_DOMAIN',
'splash_headers':{},
'dont_process_response':True,
'dont_send_headers':True,
'magic_response':False
}}
)
3.Splash响应对象
对于不同的splash请求,scrapy-splash返回不同的response子类。
- SplashResponse----二进制响应,比如对render.png的响应
- SplashTextResponse----文本响应,比如render.html
- SplashJsonResponse----JSON响应,比如render.json
4.局部代码
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url,callback=self.parse,args={'wait':3},endpoint='render.html')
再次声明
内容只是粗略介绍,但是也够基本的正常使用。草草结束,只因不知道再如何装下去。
若文本有不正确的地方 ,望指正。