scrapy 集成到 django(三) - 代理中间件

项目地址: recruitment

中间件

虽然 代理 两字在前,但本文的重点是 中间件, 利用好了中间件,算是在掌握 scrapy 的道路上迈进了一大步.

首先看看 scrapy 的架构

如图所示:

详细的官方解释可参考: scrapy架构

在这里,我们注意到 Downloader-MiddleWare ,它是在 Request(请求) 和 Response(响应) 路上的一环.
假如你是一名间谍,要去到某个公司获取机密信息,但大摇大摆的过去肯定会被发现,这时候有个人告诉你,他可以给你弄一张门禁卡.这时候这个提供门禁的人起到的中间件的作用.
同样,在请求一些网页时,需要给请求加上 headers referer proxy 等信息,让自己的爬虫绕过反爬手段.同时,在当请求失败的时候及时处理错误的请求,而且在服务器响应部分还可以加以判断,看看服务器是否返回了正确的内容回来

中间件的文档可参考: Downloader-MiddleWare

文档已经说的很详细了,这里简单介绍下吧

一个 Downloader-MiddleWare 包含了 3 个主要的部分


# 处理请求的函数
def process_request(request, spider):
    pass


# 处理响应的函数
def process_response(request, response, spider):
    pass

# 处理错误的函数
def process_exception(request, exception, spider):
    pass

这里给出一份完整的代码供参考

middleware.py


class ProxyMiddleWare():

  # 在请求中植入 UA 和 header
  def process_request(self, request, spider):

      # 给 request 添加一些参数
      # 通常代理/UA在这里添加
      ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
      request.headers.setdefault("User-Agent", ua)
      request.meta["dont_redirect"] = True
      request.meta['download_timeout'] = 5


  # 遇到问题重新构造请求
  def process_exception(self, request, exception, spider):

      # 重新构造 ua
      ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
      request.headers.setdefault("User-Agent", ua)
      # 发送新请求
      new_req = request.copy()
      return new_req


  def process_response(self, request, response, spider):

      # 请求成功
      # 则直接给 spiders 处理
      if response.status == 200:

          return response

      # 请求失败
      # 则重新构造请求
      else:
        # 重新构造 ua
        ua = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)'
        request.headers.setdefault("User-Agent", ua)
        # 发送新请求
        new_req = request.copy()
        return new_req

构造好自定义的中间件后,将其加入 settings.py 中

settings.py

DOWNLOADER_MIDDLEWARES = {

   'project.middlewares.ProxyMiddleWare': 550
}


这样,在每一次请求时,都会自动加上一个 UA, 出现请求错误或者响应内容异常时会重新构造请求

代理中间件

刚刚讲了在中间件内添加 ua ,其实添加代理 ip 也是一样的道理,在网上购买或者自己爬取一些免费的代理,加入到中间件中即可.

这里就不贴代码了,愿意仔细研究的可以参考一下我的项目

middlewares.py

这里推荐一个开源的 ip 池: IPProxyTool
然后我自己写的一个,水平不高,供参考: proxypool

posted @ 2017-08-13 23:24  zx576  阅读(455)  评论(0编辑  收藏  举报