Scrapy 框架(六)之Spider Middleware

Spider Middleware

Spider Middleware是介入到Scrapy 的 Spider 处理机制的钩子框架,当Downloader 生成 Response 之后,Response 会被发送给 Spider,在发送给 Spider 之前,Response会首先经过 Spider Middleware 处理,当 Spider处理生成 Item 和 Request 之后,Item 和Request 还会经过 Spider Middleware 的处理。

Spider Middleware有下面几个作用:

  • 可以在 Downloader 生成的 Response 发送给 Spider 之前,也就是在 Response 发送给 Spider之前对 Response 进行处理
  • 可以在 Spider 生成的 Request 发送给 Schedule 之前,也就是在 Request 发送给 Schedule 之前对 Request进行处理
  • 可以在 Spider 生成的 Item 发送给 Item Pipeline 之前,也就是在 Item 发送给 Item Pipeline 之前对 Item 进行处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class SpiderMiddleware(object):

def process_spider_input(self,response, spider):
"""
下载完成,执行,然后交给parse处理
:param response:
:param spider:
:return:
"""
pass

def process_spider_output(self,response, result, spider):
"""
spider处理完成,返回时调用
:param response:
:param result:
:param spider:
:return: 必须返回包含 Request 或 Item 对象的可迭代对象(iterable)
"""
return result

def process_spider_exception(self,response, exception, spider):
"""
异常调用
:param response:
:param exception:
:param spider:
:return: None,继续交给后续中间件处理异常;含 Response 或 Item 的可迭代对象(iterable),交给调度器或pipeline
"""
return None


def process_start_requests(self,start_requests, spider):
"""
爬虫启动时调用
:param start_requests:
:param spider:
:return: 包含 Request 对象的可迭代对象
"""
return start_requests

使用说明

其实 Scrapy 已经提供了许多的 Spider Middleware ,它们在default_settings.py文件中被SPIDER_MIDDLEWARES_BASE变量所定义。

1
2
3
4
5
6
7
8
9
SPIDER_MIDDLEWARES_BASE = {
# Engine side
'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 side
}

和 Downloader Middleware 一样,Spider Middleware 首先加入到SPIDER_MIDDLEWARES设置中,该设置会和 Scrapy 中的SPIDER_MIDDLEWARES_BASE 定义的 Spider Middleware 合并,然后根据键值得数字优先排序,得到一个有序列表。需要注意的是越小代表越靠近Scrapy引擎,数字越大越靠近Spider

核心方法

每个Spider Middleware 是一个定义了以下一个或多个方法的Python类 ,核的方法有下面四个:

1
2
3
4
process_spider_input(self,response, spider)
process_spider_output(self,response, result, spider)
process_spider_exception(self,response, exception, spider)
process_start_requests(self,start_requests, spider)
process_spider_input(self,response, spider)
  • 当 Response 被 Spider Middleware 处理时被调用
  • process_spider_input()方法返回 None 或者抛出一个异常
    • 如果返回None,Scrapy 将会继续处理该 Response,调用所有其他的 Spider Middleware,直到 Spider处理该 Response。
    • 如果抛出一个异常, Scrapy 将不会调用任何其他 Spider Middleware 的process_spider_input()方法,而调用 Request 的 errback() 方法,errback 的输出将会被重新输入到中间件中,使用process_spider_output()方法来处理,当其抛出异常时则调用process_spider_exception()方法来处理
  • 参数:
    • response (Response 对象) – 被处理的 Response
    • spider (Spider 对象) – 该Response 对应的 Spider
process_spider_output(self,response, result, spider)
  • 当 Spider 处理 Response 返回结果时被调用
  • process_spider_output()方法必须返回以下其中一个:包含Request 或者 Item 对象的可迭代对象
  • 参数:
    • response (Response 对象) – 生成该输出的 Response
    • result(包含Request或Item对象的可迭代对象) – Spider 返回的结果
    • spider (Spider 对象) – 其结果对应的 Spider
process_spider_exception(self,response, exception, spider)
  • 当 Spider 或 Spider Middleware 的 process_spider_input()方法抛出异常时被调用
  • process_spider_exception()方法必须返回以下其中一种:None、包含 Response 或 Item对象的可迭代对象
    • 如果返回None,Scrapy 将继续处理该异常,调用其他 Spider Middleware 中的process_spider_exception()方法,直到所有 Spider Middleware 都被调用。
    • 如果返回时一个可迭代对象,那么其他 Spider Middleware 的process_spider_exception()方法不会被调用,而是调用process_spider_output()方法
  • 参数:
    • response (Response 对象) – 异常被抛出时被处理的 Response
    • exception(Exception对象) – 被抛出的异常
    • spider (Spider 对象) – 抛出该异常的 Spider
process_start_requests(self,start_requests, spider)
  • 当爬虫启动时调用
  • process_start_requests()方法必须返回包含Request 对象的可迭代对象
  • 参数:
    • start_requests (包含Request的可迭代对象) – Start Requests
    • spider (Spider 对象) – Start Requests 所属 Spider
-------------本文结束感谢您的阅读-------------

本文标题:Scrapy 框架(六)之Spider Middleware

文章作者:GavinLiu

发布时间:2018年05月07日 - 21:05

最后更新:2018年05月07日 - 15:05

原始链接:http://gavinliu4011.github.io/post/c8ce4f9f.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

请博主吃个鸡腿吧
0%