Scrapy框架之Scrapy-Splash的使用

Scrapy-Splash插件的介绍与安装, 最后通过一个实际的例子介绍Scrapy-Splash的使用

前提

熟练使用Scrapy框架做基本的爬虫开发

Scrapy-Splash?

splash是一个JavaScript渲染服务。它是一个实现了HTTP API的轻量级浏览器,splash使用python实现的,同时使用Twisted和QT.

scrapy-splash 是为了方便scrapy框架使用splash而进行的封装。它能与scrapy框架更好的结合,相比较于在python中 使用requests库或者使用scrapy 的Request对象来说,更为方便,而且能更好的支持异步。

Why Scrapy-Splash?

随着越来越多的网站开始用JS在客户端浏览器动态渲染网站,导致很多我们需要的数据并不能由原始的html中获取,再加上Scrapy本身并不提供JS渲染解析的功能,这时候Scrapy-Splash就有了用武之地.

Scrapy-Splash Install

因为Scrapy-Splash必须在docker中使用, 所以首先得安装docker, 安装docker的方式这里不做介绍了. 我这里使用的机器是Ubuntu18.04, 在Ubuntu18.04上安装docker参考文章: 在Ubuntu18.04上安装docker

安装完docker之后, 通过sudo docker run -p 8050:8050 scrapinghub/splash启动Scrapy-Splash, 在浏览器中输入: http://localhost:8050/, 如果显示的是以下界面这一切操作成功:

《Scrapy框架之Scrapy-Splash的使用》 scrapy-splash界面.png

Scrapy-Splash Usage

这里以抓取某篇具体小说为例: 小说地址为 http://www.biqugedu.com/0_25/, 这里我们要抓取它的封面图.

《Scrapy框架之Scrapy-Splash的使用》 xpath路经.png

通过在浏览器中分析, 封面图的xpath路经为: //div[@id=’fmimg’]/img/@src, 然后我们编写一个parse解析方式, 打印出抓取到的封面图地址:

    def parse(self, response):
        print(response.xpath("//div[@id='fmimg']/img/@src").extract_first())

往Redis中推送任务后运行爬虫, 发现输出为:

2019-02-27 10:07:21 [scrapy.core.engine] INFO: Spider opened
2019-02-27 10:07:23 [dmoz] DEBUG: Resuming crawl (1 requests scheduled)
2019-02-27 10:07:23 [scrapy.extensions.logstats] INFO: Crawled 0 pages (at 0 pages/min), scraped 0 items (at 0 items/min)
2019-02-27 10:07:23 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-02-27 10:07:27 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.biqugedu.com/0_25/> (referer: None)
None
2019-02-27 10:07:28 [dmoz] INFO: no task sleep 30s
2019-02-27 10:07:32 [scrapy.crawler] INFO: Received SIGINT, shutting down gracefully. Send again to force 
2019-02-27 10:07:32 [scrapy.core.engine] INFO: Closing spider (shutdown)

很显然没有抽取到我们期望的内容, 然后回过头来发现, 原页面中封面地址实际上是通过一个js脚本加载的, 而在浏览器中能够看到xpath是因为浏览器已经帮我们把这个js加载好了, 但是Scrapy框架则只会请求这个小说的文件, 不会加载其中的js, 如果想要加载js, 这个时候就需要Scrapy-Splash就登场了.

在开始使用Scrapy-Splash之前, 先把这个小说地址添加到Splash中Render一下(上边提到的启动Splash服务后在浏览器中输入http://localhost:8050), 然后可以看到正常获取到了图片地址

《Scrapy框架之Scrapy-Splash的使用》 Splash Render后的结果

接下来, pip install scrapy_splash安装scrapy_splash, 然后编写一个start_requests方法:

def start_requests(self):
    splah_args = {
        "lua_source": """
        function main(splash, args)
          assert(splash:go(args.url))
          assert(splash:wait(0.5))
          return {
            html = splash:html(),
            png = splash:png(),
            har = splash:har(),
          }
        end
        """
    }
    headers = {
        'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) '
                      'Chrome/72.0.3626.109 Safari/537.36',
    }
    yield SplashRequest(url="http://www.biqugedu.com/0_25/", callback=self.parse, args=splah_args, 
 headers=headers)

然后在settings文件中进行如下配置:

# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html
SPIDER_MIDDLEWARES = {
   'scrapy_splash.SplashDeduplicateArgsMiddleware': 100,
}

# See http://scrapy.readthedocs.org/en/latest/topics/downloader-middleware.html
DOWNLOADER_MIDDLEWARES = {
    'scrapy_splash.SplashCookiesMiddleware': 723,
    'scrapy_splash.SplashMiddleware': 725,
    'scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware': 810,  # 不配置查不到信息
}

HTTPCACHE_ENABLED = True
HTTPCACHE_EXPIRATION_SECS = 0
HTTPCACHE_DIR = 'httpcache'

SPLASH_URL = "http://localhost:8050/"  # 自己安装的docker里的splash位置
# DUPEFILTER_CLASS = "scrapy_splash.SplashAwareDupeFilter"
HTTPCACHE_STORAGE = 'scrapy_splash.SplashAwareFSCacheStorage'

这时再启动爬虫程序, 结果如下:

2019-02-27 10:45:17 [scrapy.extensions.httpcache] DEBUG: Using filesystem cache storage in /home/tiger/PycharmProjects/tutorial/.scrapy/httpcache
2019-02-27 10:45:17 [scrapy.extensions.telnet] INFO: Telnet console listening on 127.0.0.1:6023
2019-02-27 10:45:25 [scrapy.core.engine] DEBUG: Crawled (200) <GET http://www.biqugedu.com/0_25/ via http://localhost:8050/render.html> (referer: None)
http://www.biqugedu.com/files/article/image/0/25/25s.jpg
2019-02-27 10:45:25 [dmoz] INFO: no task sleep 30s

正常输出了封面图的地址.

    原文作者:HideSidePush
    原文地址: https://www.jianshu.com/p/41e0a7e40824
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞