Splash动态页面爬虫

Splash是一个Javascript渲染服务。它是一个实现了HTTP API的轻量级浏览器,Splash是用Python实现的,同时使用Twisted和QT。Twisted(QT)用来让服务具有异步处理能力,以发挥webkit的并发能力。
scrapy-splash利用Splash将javascript和Scrapy集成起来,使得Scrapy可以抓取动态网页。
地址:http://scrapy-cookbook.readthedocs.io/zh_CN/latest/scrapy-12.html#scrapy-splash

一、安装运行splash
1、docker中安装splash
docker pull scrapinghub/splash

2、使用docker启动服务命令启动Splash服务
#启动splash服务,并通过http,https,telnet提供服务
#通常一般使用http模式 ,可以只启动一个8050就好  
#Splash 将运行在 0.0.0.0 at ports 8050 (http), 8051 (https) and 5023 (telnet).
docker run -it --name mysplash -p 5023:5023 -p 8050:8050 -p 8051:8051 -d -max-timeout 3600 scrapinghub/splash bash

3、打开浏览器输入192.168.104.53:8050查看服务启动情况

4、输入www.baidu.com,点击Render me按钮,立马可以看见在服务器端渲染后的百度页面

二、安装配置scrapy-splash
1、安装scrapy-splash
$ pip install scrapy-splash

2、配置
在你的scrapy工程的配置文件settings.py中添加
SPLASH_URL = 'http://192.168.104.53:8050'

添加Splash中间件,还是在settings.py中通过DOWNLOADER_MIDDLEWARES指定,并且修改HttpCompressionMiddleware的优先级
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,
}

默认情况下,HttpProxyMiddleware的优先级是750,要把它放在Splash中间件后面
设置Splash自己的去重过滤器
DUPEFILTER_CLASS = 'scrapy_splash.SplashAwareDupeFilter'

如果你使用Splash的Http缓存,那么还要指定一个自定义的缓存后台存储介质,scrapy-splash提供了一个scrapy.contrib.httpcache.FilesystemCacheStorage的子类
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

如果你要使用其他的缓存存储,那么需要继承这个类并且将所有的scrapy.util.request.request_fingerprint调用替换成scrapy_splash.splash_request_fingerprint

三、使用
主要通过重写start_requests函数,修改其中渲染请求的方式
1、使用scrapy_splash.SplashRequest渲染
def start_requests(self):
        splash_args = {
            'wait': 0.5,
            # 'http_method': 'GET',
            # 'html': 1,
    # 'png': 1,
               # 'width': 600,
        # 'render_all': 1
        }
        for url in self.start_urls:
            yield scrapy_splash.SplashRequest(url, self.parse, endpoint='render.html',
                                args=splash_args)

2、在普通的scrapy请求中传递splash请求meta关键字达到同样的效果
def start_requests(self):
        meta_args = {
            'splash': {
                'args': {
                    'wait': 0.5,
                    # set rendering arguments here
                    #'render_all':1,
                    'images': 0,
                    'html': 1,

                    # 'url' is prefilled from request url
                    # 'http_method' is set to 'POST' for POST requests
                    # 'body' is set to request body for POST requests
                },

                # optional parameters
                'endpoint': 'render.html',  # optional; default is render.json
                #'splash_url': '<url>',      # optional; overrides SPLASH_URL
                'slot_policy': scrapy_splash.SlotPolicy.PER_DOMAIN,
                'splash_headers': {},       # optional; a dict with headers sent to Splash
                'dont_process_response': True,  # optional, default is False
                'dont_send_headers': True,  # optional, default is False
                'magic_response': False,    # optional, default is True
            }
        }
        for url in self.start_urls:
            yield scrapy.Request(url, self.parse, meta=meta_args)

Splash API说明,使用SplashRequest是一个非常便利的工具来填充request.meta['splash']里的数据
meta[‘splash’][‘args’] 包含了发往Splash的参数。
meta[‘splash’][‘endpoint’] 指定了Splash所使用的endpoint,默认是render.html
meta[‘splash’][‘splash_url’] 覆盖了settings.py文件中配置的Splash URL
meta[‘splash’][‘splash_headers’] 运行你增加或修改发往Splash服务器的HTTP头部信息,注意这个不是修改发往远程web站点的HTTP头部
meta[‘splash’][‘dont_send_headers’] 如果你不想传递headers给Splash,将它设置成True
meta[‘splash’][‘slot_policy’] 让你自定义Splash请求的同步设置
meta[‘splash’][‘dont_process_response’] 当你设置成True后,SplashMiddleware不会修改默认的scrapy.Response请求。默认是会返回SplashResponse子类响应比如SplashTextResponse
meta[‘splash’][‘magic_response’] 默认为True,Splash会自动设置Response的一些属性,比如response.headers,response.body等
如果你想通过Splash来提交Form请求,可以使用scrapy_splash.SplashFormRequest,它跟SplashRequest使用是一样的。

猜你喜欢

转载自blog.csdn.net/zhifeng172/article/details/78895942