返回介绍

13.6 Spider 中间件

发布于 2024-01-26 22:39:51 字数 4045 浏览 0 评论 0 收藏 0

从Scrapy框架图12-1中可以看到,Spider中间件是介入到Scrapy的Spider处理机制的钩子框架,可以用来处理发送给Spiders的Response及Spider产生的Item和Request。

13.6.1 激活Spider中间件

和下载器中间件一样,Spider也是需要激活才能使用的。要启用Spider中间件,需要将其加入到SPIDER_MIDDLEWARES设置中。该设置和DOWNLOADER_MIDDLEWARES一样,键是中间件的路径,值为中间件的顺序。示例如下:

  SPIDER_MIDDLEWARES = {
     'myproject.middlewares.CustomSpiderMiddleware': 543,
  }

在Settings.py中对SPIDER_MIDDLEWARES的设置,会与Scrapy内置的Spider中间件设置SPIDER_MIDDLEWARES_BASE合并,但是不会覆盖,而是根据顺序值进行排序,最后得到启用中间件的有序列表:第一个中间件是最靠近引擎的,最后一个中间件是最靠近Spider的。Scrapy内置的spider中间件设置SPIDER_MIDDLEWARES_BASE为:

·'scrapy.spidermiddlewares.httperror.HttpErrorMiddleware':50

·'scrapy.spidermiddlewares.offsite.OffsiteMiddleware':500

·'scrapy.spidermiddlewares.referer.RefererMiddleware':700

·'scrapy.spidermiddlewares.urllength.UrlLengthMiddleware':800

·'scrapy.spidermiddlewares.depth.DepthMiddleware':900

如何分配中间件的位置,首先看一下内置的中间件的位置,然后根据将你想放置的中间件的位置设置一个值。有时候你想放置的中间件可能会依赖前后的中间件的作用,因此设置顺序相当重要。如果想禁用内置的中间件,必须在SPIDER_MIDDLEWARES中定义该中间件,并将值设置为None。例如想关闭(off-site)中间件:

  SPIDER_MIDDLEWARES = {
     'myproject.middlewares.CustomSpiderMiddleware': 543,
     'scrapy.contrib.spidermiddleware.offsite.OffsiteMiddleware': None,
  }

注意  SPIDER_MIDDLEWARES_BASE中内置中间件并不是都开启的,有些中间件需要通过特定的设置来启用。

13.6.2 编写Spider中间件

编写spider中间件十分简单,和下载器中间件非常类似,每个中间件组件是定义了以下一个或多个方法的Python类:

·process_spider_input(response,spider)

·process_spider_output(response,result,spider)

·process_spider_exception(response,exception,spider)

·process_start_requests(start_requests,spider)

下面分别介绍这四种中间件。

1.process_spider_input(response,spider)

方法说明: 当response通过spider中间件时,该方法被调用,处理该response。应该返回None或者抛出一个异常。

参数:

·response(Response对象):被处理的response

·spider(Spider对象):该response对应的spider

返回:

如果返回None,Scrapy将会继续处理该response,调用所有其他的中间件直到spider处理该response。

如果产生一个异常,Scrapy将不会调用任何其他中间件的process_spider_input()方法,并调用request的errback。errback的输出将会以另一个方向被重新输入到中间件链中,使用process_spider_output()方法来处理,当其抛出异常时,则调用process_spider_exception()。

2.process_spider_output(response,result,spider)

方法说明: 当Spider处理Response返回Result时,该方法被调用。

参数:

·response(Response对象):生成该输出的Response。

·result:Spider返回的Result,是包含Request、Dict或Item的可迭代对象。

·spider(Spider对象):其结果被处理的Spider。

返回: process_spider_output()必须返回包含Request、dict或Item对象的可迭代对象(iterable)。

3.process_spider_exception(response,exception,spider)

方法说明: 当Spider或(其他Spider中间件的)process_spider_input()抛出异常时,该方法被调用。该方法必须返回None或者包含Response、Dict或Item对象的可迭代对象中。

参数:

·response(Response对象):异常被抛出时被处理的Response。

·exception(Exception对象):被抛出的异常。

·spider(Spider对象):抛出该异常的Spider。

返回:

·如果其返回None,Scrapy将继续处理该异常,调用中间件链中的其他中间件的process_spider_exception()方法,直到所有中间件都被调用,该异常到达引擎时被记录,最后被忽略。

·如果返回一个可迭代对象,则中间件链的process_spider_output()方法被调用,其他的process_spider_exception()将不会被调用。

4.process_start_requests(start_requests,spider)

方法说明: 该方法以spider启动的request为参数,执行的过程类似于process_spider_output(),其接受一个可迭代的对象(start_requests参数)且必须返回另一个包含Request对象的可迭代对象。

参数:

·start_requests(包含Request的可迭代对象):起始Requests。

·spider(Spider对象):起始Requests所属的Spider。

下面通过一个例子帮助大家理解Spider中间件的编写,中间件的功能是实现Request中的URL规范化,示例代码如下:

  from scrapy.http import Request
  from scrapy.utils.url import canonicalize_url
  
  class UrlCanonicalizerMiddleware(object):
     def process_spider_output(self, response, result, spider):
       for r in result:
            if isinstance(r, Request):
              curl = canonicalize_url(r.url)
              if curl != r.url:
                r = r.replace(url=curl)
            yield r

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文