小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware

1,954 阅读5分钟

人生苦短,我用 Python

前文传送门:

小白学 Python 爬虫(1):开篇

小白学 Python 爬虫(2):前置准备(一)基本类库的安装

小白学 Python 爬虫(3):前置准备(二)Linux基础入门

小白学 Python 爬虫(4):前置准备(三)Docker基础入门

小白学 Python 爬虫(5):前置准备(四)数据库基础

小白学 Python 爬虫(6):前置准备(五)爬虫框架的安装

小白学 Python 爬虫(7):HTTP 基础

小白学 Python 爬虫(8):网页基础

小白学 Python 爬虫(9):爬虫基础

小白学 Python 爬虫(10):Session 和 Cookies

小白学 Python 爬虫(11):urllib 基础使用(一)

小白学 Python 爬虫(12):urllib 基础使用(二)

小白学 Python 爬虫(13):urllib 基础使用(三)

小白学 Python 爬虫(14):urllib 基础使用(四)

小白学 Python 爬虫(15):urllib 基础使用(五)

小白学 Python 爬虫(16):urllib 实战之爬取妹子图

小白学 Python 爬虫(17):Requests 基础使用

小白学 Python 爬虫(18):Requests 进阶操作

小白学 Python 爬虫(19):Xpath 基操

小白学 Python 爬虫(20):Xpath 进阶

小白学 Python 爬虫(21):解析库 Beautiful Soup(上)

小白学 Python 爬虫(22):解析库 Beautiful Soup(下)

小白学 Python 爬虫(23):解析库 pyquery 入门

小白学 Python 爬虫(24):2019 豆瓣电影排行

小白学 Python 爬虫(25):爬取股票信息

小白学 Python 爬虫(26):为啥买不起上海二手房你都买不起

小白学 Python 爬虫(27):自动化测试框架 Selenium 从入门到放弃(上)

小白学 Python 爬虫(28):自动化测试框架 Selenium 从入门到放弃(下)

小白学 Python 爬虫(29):Selenium 获取某大型电商网站商品信息

小白学 Python 爬虫(30):代理基础

小白学 Python 爬虫(31):自己构建一个简单的代理池

小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门

小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)

小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)

小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器

小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware

引言

Spider Middleware 是 Scrapy 的 Spider 处理机制的一个钩子框架,我们可以在其中插入自定义功能,以处理发送到 Spider 进行处理的响应以及处理 Spider 生成的请求和项目。

内置爬虫中间件

和前文介绍过的 Downloader Middleware 一样, Scrapy 同样为我们内置了一部分的 Spider Middleware ,这些内置的 Spider Middleware 被保存在变量 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,
}

同样和 Downloader Middleware 一样的是, Spider Middleware 会被加入到 SPIDER_MIDDLEWARES 的设置中,该设置会和 Scrapy 中定义的 SPIDER_MIDDLEWARES_BASE 合并,根据数值的大小进行优先级排序,第一个 Middleware 是靠近引擎的,最后一个 Middleware 是靠近 Spider 的。

自定义爬虫中间件

Scrapy 内置的 Spider Middleware 只提供了一些基础的功能,我们如果需要扩展其功能,实现一个自定义的爬虫中间件,只需要实现以下某几个方法即可。

核心方法如下:

  • processspiderinput(response, spider)
  • processspideroutput(response, result, spider)
  • processspiderexception(response, exception, spider)
  • processstartrequests(start_requests, spider)

只需要实现其中一个方法就可以定义一个爬虫中间件。

processspiderinput(response, spider)

参数:

response (response 对象)–正在处理的响应

spider (spider 对象)–此响应预期用于的蜘蛛

对于通过 Spider Middleware 并进入 Spider 进行处理的每个响应,都会调用此方法。

processspiderinput() )应该返回 None 或引发异常。

如果返回 None ,则 Scrapy 将继续处理此响应,并执行所有其他中间件,直到最终将响应交给蜘蛛进行处理。

如果引发异常, Scrapy 不会费心调用任何其他蜘蛛中间件 processspiderinput() ,并且会在存在错误时调用请求 errback ,否则它将启动 processspiderexception() 链。 errback 的输出在另一个方向上链回,以供 processspideroutput() 处理,或者如果引发异常,则链接到 processspiderexception() 。

processspideroutput(response, result, spider)

参数:

response ( response 对象)–从蜘蛛生成此输出的响应

result (可迭代的 Request , dict 或 Item 对象)– spider 返回的结果

spider ( spider 对象)–正在处理其结果的蜘蛛

处理完响应后,将使用 Spider 从返回的结果中调用此方法。

processspideroutput() 必须返回 Request , dict 或 Item 对象的可迭代对象。

processspiderexception(response, exception, spider)

参数:

response ( response 对象)–引发异常时正在处理的响应

exception (Exception对象)–引发的异常

spider ( spider 对象)–引发异常的蜘蛛

当 Spider 或 processspideroutput() 方法(来自先前的 Spider 中间件)引发异常时,将调用此方法。

processspiderexception() 应该返回 None 或可迭代的 Request , dict 或 Item 对象。

如果返回 None ,则 Scrapy 将继续处理此异常,并在以下中间件组件中执行任何其他 processspiderexception() ,直到没有剩余中间件组件且异常到达引擎为止(记录并丢弃该异常)。

如果返回可迭代,则从下一个蜘蛛中间件开始, processspideroutput() 管道将启动,并且不会调用其他 processspiderexception() 。

processstartrequests(start_requests, spider)

参数:

start_requests (可迭代的 Request )–启动请求

spider ( spider 对象)–启动请求所属的蜘蛛

此方法是由 Spider 的启动请求调用的,其工作原理与 processspideroutput() 方法类似,不同之处在于它没有关联的响应,并且仅返回请求(不返回项目)。

它接收一个可迭代的(在 start_requests 参数中),并且必须返回另一个可迭代的 Request 对象。

在实际使用过程中, Spider Middleware 的使用率并不如 Downloader Middleware 高,小编这里就不做示例了,在一些必要的情况下, Spider Middleware 可以用作一些数据处理。

参考

https://docs.scrapy.org/en/latest/topics/spider-middleware.html

如果我的文章对您有帮助,请扫码关注下作者的公众号:获取最新干货推送:)