scrapy中使用Splash

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'

支持 cache_ars(可选)

SPIDER_MIDDLEWARES = {
 'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

开启Splash的两个下载器中间件并调整HttpCompressionMiddleware的次序

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())

你可能感兴趣的:(Scrapy)