做爬虫的朋友经常会遇到一些动态加载的网站,比较常见的做法是使用selenium调用一个浏览器来加载,但是这种方法感觉大材小用,比较浪费资源,且效率低 。这个时候我们可以使用Splash。Splash可以执行用Lua 编程语言编写的自定义渲染脚本。这允许我们使用Splash作为类似于PhantomJS的浏览器自动化工具。
1.安装splash。
手动安装的话比较麻烦,这里推荐使用docker拉取镜像。
手动安装:
git clone https://github.com/scrapinghub/splash/
安装依赖: cd splash/dockerfiles/splash
sudo cp ./qt-installer-noninteractive.qs /tmp/script.qs
sudo ./provision.sh \
prepare_install \
install_msfonts \
install_extra_fonts \
install_deps \
install_flash \
install_qtwebkit_deps \
install_official_qt \
install_qtwebkit \
install_pyqt5 \
install_python_deps
sudo pip3 install splash/
开启splash服务,默认监听8050端口 python3 -m splash.server
使用docker拉取镜像
如果你还没有安装docker 请先安装docker, 安装好docker后直接拉取镜像就可以了
docker pull scrapinghub/splash
运行: docker run -p 8050:8050 scrapinghub/splash
运行成功后在浏览器中打开 http://127.0.0.1:8050/ 可以看到
2.安装scrapy-splash
pip3 install scrapy-splash
3.在scrapy中使用
首先我找了 一个京东js加载的页面 https://item.jd.com/5089253.html
这个页面的价格是 用js加载的,如果我们直接获取这个页面会得到这样的结果
可以看到是没有加载价格的,但是原网页是 有价格 的
好吧,现在我们使用scrapy+splash来获取这个js加载的价格。
我们只需要重新定义scrapy.Spider的start_requests方法 和 设置setting就可以了
这是spider的代码
# -*- coding: utf-8 -*-
import scrapy
from scrapy_splash import SplashRequest
class SjbSpider(scrapy.Spider):
name = 'iphonex'
allowed_domains = ['www.jd.com']
start_urls = ['https://item.jd.com/5089253.html']
def start_requests(self):
for url in self.start_urls:
yield SplashRequest(url,self.parse,args={'wait':'0.5'})
def parse(self, response):
price =response.xpath('/html/body/div[8]/div/div[2]/div[4]/div/div[1]/div[2]/span[1]/span[2]/text()').extract_first()
print("价格:",price)
这是setting需要添加的代码
SPLASH_URL = 'http://127.0.0.1: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'
这只是个小测试,scrapy其他的地方我都没有动,我们可以看到现在已经可以抓取到由js加载的价格了