在做爬虫的时候,大多数的网页中会存在数据动态加载的部分,而且多数都是后期渲染上的。正常情况下爬虫程序仅能爬取被渲染过的数据。因此我们看到的数据也许并非是爬虫直接获取来的。
而scrapy-splash担任了一个中间人的角色,程序通过splash服务请求网站,并获得splash返回的JS渲染后的网页。
原因
像selenium、phantomjs都是常用的渲染网页的工具。
就拿selenium来说,需要通过加载一个浏览器内核来进行渲染,效率有点低。而且与Scrapy集成需要实现一个downloder middleware,操作起来有些许的复杂,对我这种懒人来说简直折磨。
而scrapy-deltafetch的出现,仅仅几行配置就解决了这些问题。
安装
模块安装
安装scrapy-deltafetch模块。
pip3 install scrapy-splash
docker容器
这里首先要安装docker服务,然后执行命令拉取splash的镜像,启动容器即可。
docker pull scrapinghub/splash
docker run -d -p 8050:8050 scrapinghub/splash --disable-private-mode
拉取docker镜像:
开放8050端口,在浏览器输入你的ip:8050,访问到如下页面表示容器启动成功。
应用
配置
在settings.py中添加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,
}
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
「SPLASH_URL」中的IP根据实际情况来填写。
请求
原本使用Request来请求网站,这里要修改成SplashRequst。
from scrapy_splash import SplashRequest
# 原本是yield Request()
yield SplashRequest()
这样,我们访问的url是先经过splash服务的。启动程序,查看日志。
测试
render
这里先在splash提供的页面上测试一把。
splash会请求这个网页的图片、js等,并会渲染后的网页返回给程序。
代码测试
对一个url同时进行普通请求和splash请求。
def start_requests(self):
yield Request(url=self.start_urls[0], callback=self.parse)
yield SplashRequest(url=self.start_urls[0], callback=self.parse_splash)
def parse(self, response):
comment = response.css('div.at-feed-ellipsis__text::text').extract()
print('Request', comment)
def parse_splash(self, response):
comment = response.css('div.at-feed-ellipsis__text::text').extract()
print('SplashRequest', comment)
同时对评论区进行爬取。运行结果如下:
上述样例仅用于学习用途。
结语
就我个人而言,依赖于插件总归不如自己去看看那些动态加载的API,分析之后可以直接模拟请求获取数据。
但是使用scrapy-splash会便利很多,也没有很高的技术门槛,所以还是值得一学的。