scrapy爬虫框架没有提供页面js渲染服务,所以我们获取不到信息,我们可以使用selenium或者scrapy-splash,
Selenium极大地方便了动态页面的数据提取,但是它需要操作浏览器,无法实现异步和大规模页面的爬取需求。
Splash就可以解决上述问题
1、Splash渲染引擎简介:
Splash是为Scrapy爬虫框架提供渲染javascript代码的引擎,它有如下功能:(摘自维基百科)
(1)为用户返回渲染好的html页面
(2)并发渲染多个页面
(3)关闭图片加载,加速渲染
(4)执行用户自定义的js代码
(5)执行用户自定义的lua脚步,类似于无界面浏览器phantomjs
2、在使用Splash前,需要安装以下3个工具或模块。
Splash:一个JavaScript的渲染服务,带有HTTP API的轻量级Web浏览器。
Docker:一种容器引擎,Splash需要在Docker中安装和运行。
Scrapy-Splash:实现Scrapy中使用Splash的模块。
2.1、下载和安装 docker
以Windows下安装Docker为例。不同的Windows版本,Docker的安装包不一样,主要分为两种:(1)Windows 10专业版及企业版64位:下载Docker for Windows。官方下载地址为https://store.docker.com/editions/community/docker-ce-desktop-windows。
(2)其他Windows版本:下载Docker toolbox。这是一个Docker工具集。官方下载地址为https://docs.docker.com/toolbox/overview/#ready-to-get-started。国内可以使用阿里云的镜像来下载,下载地址为http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/。
关于Linux和Mac OS下的Docker安装及使用,官方网站都有详细的教程,地址为https://docs.docker.com/,读者也可以参考菜鸟网络,地址为http://www.runoob.com/docker/windows-docker-install.html
2.2 拉取和开启Splash
docker 启动后,执行命令拉取splash 镜像:
docker pull scrapinghub/splash
开启 splash 命令为:
前台运行 sudo docker run -p 8050:8050 scrapinghub/splash
后台运行 sudo docker run -d -p 8050:8050 scrapinghub/splash
访问 http://127.0.0.1:8050页面查看下启动情况
2.3 Scrapy-Splash的安装
pip install scrapy-splash
官方文档链接为:https://splash.readthedocs.io/en/latest/index.html
2.4 配置scrapy-splash环境
在项目配置文件settings.py中,需要配置scrapy-splash,配置内容如下:
#设置Splash服务器地址(ip和port 为docker 中的ip和port )
SPLASH_URL = ‘http://ip:port’
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'
SPIDER_MIDDLEWARES = {
'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}
DOWNLOAD_MIDDLEWARES = {
#将splash middleware 添加到DOWNLOAD_MIDDLEWARE中
'scrapy_splash.SplashCookieMiddleware': 723,
'scrapy_splash.SplashMiddleware': 725,
'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}
spiders中
from scrapy import Request
from scrapy.spiders import Spider
from yihaodian.items import YihaodianItem
from scrapy_splash import SlashRequest
lua_script = """
function main(splash, args)
splash:go(args.url)
splash:wait(args.wait)
splash:runjs("document.getElementByClassName('mod_trun_page clearfix mt20')[0].scrollIntoView(true)")
splash:wait(args.wait)
return splash:html()
end
"""
class PhoneSpider(Spider):
name = 'spider'
allowed_domains = ['quotes.toscrape.com']
start_urls = ['http://quotes.toscrape.com/js/']
def start_requests(self):
yield SplashRequest(self.url, callback=self.parse, endpoint='execute', args={'lua_source':lua_script, 'images':0, 'wait':3}, cahce_args=['lua_source'])
def start_requests(self): #重新定义起始爬取点
for url in self.start_urls:
yield SplashRequest(url,args = {'timeout':8,'images':0})
def start_requests(self):
for start_url in self.start_urls:
yield SplashRequest(start_url,
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())