Spider Middleware是介入到Scrapy的Spider处理机制的钩子框架。咱们首先来看看它的架构,以下图所示。
html
当Downloader生成Response以后,Response会被发送给Spider,在发送给Spider以前,Response会首先通过Spider Middleware处理,当Spider处理生成Item和Request以后,Item和Request还会通过Spider Middleware的处理。bash
Spider Middleware有以下三个做用。微信
咱们能够在Downloader生成的Response发送给Spider以前,也就是在Response发送给Spider以前对Response进行处理。网络
咱们能够在Spider生成的Request发送给Scheduler以前,也就是在Request发送给Scheduler以前对Request进行处理。架构
咱们能够在Spider生成的Item发送给Item Pipeline以前,也就是在Item发送给Item Pipeline以前对Item进行处理。框架
须要说明的是,Scrapy其实已经提供了许多Spider Middleware,它们被SPIDER_MIDDLEWARES_BASE
这个变量所定义。
scrapy
SPIDER_MIDDLEWARES_BASE
变量的内容以下:ide
{
'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,
}复制代码
和Downloader Middleware同样,Spider Middleware首先加入到SPIDER_MIDDLEWARES
设置中,该设置会和Scrapy中SPIDER_MIDDLEWARES_BASE
定义的Spider Middleware合并。而后根据键值的数字优先级排序,获得一个有序列表。第一个Middleware是最靠近引擎的,最后一个Middleware是最靠近Spider的。ui
Scrapy内置的Spider Middleware为Scrapy提供了基础的功能。若是咱们想要扩展其功能,只须要实现某几个方法便可。
url
每一个Spider Middleware都定义了如下一个或多个方法的类,核心方法有以下4个。
process_spider_input(response, spider)
。
process_spider_output(response, result, spider)
。
process_spider_exception(response, exception, spider)
。
process_start_requests(start_requests, spider)
。
只须要实现其中一个方法就能够定义一个 Spider Middleware。下面咱们来看看这4个方法的详细用法。
当Response被Spider Middleware处理时,process_spider_input()
方法被调用。
process_spider_input()
方法的参数有以下两个。
response
,是Response对象,即被处理的Response。
spider
,是Spider对象,即该Response对应的Spider。
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()
来处理。
当Spider处理Response返回结果时,process_spider_output()
方法被调用。
process_spider_output()
方法的参数有以下三个。
response
,是Response对象,即生成该输出的Response。
result
,包含Request或Item对象的可迭代对象,即Spider返回的结果。
spider
,是Spider对象,即其结果对应的Spider。
process_spider_output()
必须返回包含Request或Item对象的可迭代对象。
当Spider或Spider Middleware的process_spider_input()
方法抛出异常时,process_spider_exception()
方法被调用。
process_spider_exception()
方法的参数有以下三个。
response
,是Response对象,即异常被抛出时被处理的Response。
exception
,是Exception对象,即被抛出的异常。
spider
,是Spider对象,即抛出该异常的Spider。
process_spider_exception()
必需要么返回None
,要么返回一个包含Response或Item对象的可迭代对象。
若是它返回None
,Scrapy将继续处理该异常,调用其余Spider Middleware中的process_spider_exception()
方法,直到全部Spider Middleware都被调用。
若是它返回一个可迭代对象,则其余Spider Middleware的process_spider_output()
方法被调用,其余的process_spider_exception()
不会被调用。
process_start_requests()
方法以Spider启动的Request为参数被调用,执行的过程相似于process_spider_output()
,只不过它没有相关联的Response,而且必须返回Request。
process_start_requests()
方法的参数有以下两个。
start_requests
,是包含Request的可迭代对象,即Start Requests。
spider
,是Spider对象,即Start Requests所属的Spider。
process_start_requests()
必须返回另外一个包含Request对象的可迭代对象。
本节介绍了Spider Middleware的基本原理和自定义Spider Middleware的方法。Spider Middleware使用的频率不如Downloader Middleware的高,在必要的状况下它能够用来方便数据的处理。
本资源首发于崔庆才的我的博客静觅: Python3网络爬虫开发实战教程 | 静觅
如想了解更多爬虫资讯,请关注个人我的微信公众号:进击的Coder
weixin.qq.com/r/5zsjOyvEZ… (二维码自动识别)