scrapy 实战(四)如何抓取通过js生成的页面

2017-01-24

上期主要介绍了如何将抓取地页面同步到服务端。

本期,主要介绍如何抓取通过js生成的页面。


Scrapy 自身不能执行 js。我们必须给她写个插件

这里需要用到可以执行 js 的工具。

phantomjs 或者 python- splash

python-splash 这里不做介绍了。又兴趣的童鞋可以参考 这里 >> scrapy-splash 简单易懂方便安装。


接下来主要介绍下 scrapy + phantomjs

首先,在 settings.py 中加入一下配置:

# Enable or disable spider middlewares  
# See http://scrapy.readthedocs.org/en/latest/topics/spider-middleware.html

SPIDER_MIDDLEWARES = {  
        'andromeda.middlewares.downloader.PhantomJSDownloader': 100, #加入 phantomjs 下载中间件
    }

PHANTOMJS_PATH    = '/usr/local/bin/phantomjs' # 指定 phantomjs 的路径
PHANTOMJS_SPIDER  = ['guoku']                  # 配置 那些 spider 需要用到 phantmjs 抓取 

注:phantomjs 抓取页面开销很大。非必需,不建议采用

接着找到 middlewares/downloader.py 这个文件

    # coding=utf-8  
      
    from scrapy.http import HtmlResponse  
    from selenium import webdriver          #导入 selenium 链接 phantomjs 驱动  
    # from urlparse import urlparse  
      
    from andromeda import settings  
    import logging  
      
      
    class PhantomJSDownloader(object):  
      
        def process_request(self, request, spider):   
            response    = None  
            if spider.name in settings.PHANTOMJS_SPIDER:     
                browser = webdriver.PhantomJS(executable_path=settings.PHANTOMJS_PATH)  
                try:  
                    browser.set_window_size(800, 600) # 设置浏览器屏幕尺寸  
                    browser.get(request.url)  
                    content     = browser.page_source.encode("utf-8")  
                    url         = browser.current_url.encode('utf-8')  
                    response = HtmlResponse(url, encoding='utf-8', status=200, body=content)  
                except Exception as e:  
                    logging.error(e.message)  
                finally:  
                    browser.close()   # 关闭 selenium   
                return response       # 返回响应结果  
      
        def process_response(self, request, response, spider):  
            return response  

解释下以上代码:

  1. 给 scrapy 写下载中间件 主要重写 def process_request(self, request, spider):这个方法
  2. browser.set_window_size(800, 600) 设置浏览器屏幕尺寸
  3. content = browser.page_source.encode("utf-8") 获取 phantomjs 加载的页面。
  4. 页面抓取完成,一定要关闭浏览器。

项目源代码