人生苦短,我用 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 只提供了一些基础的功能,我们如果需要扩展其功能,实现一个自定义的爬虫中间件,只需要实现以下某几个方法即可。

核心方法如下:

  • process_spider_input(response, spider)
  • process_spider_output(response, result, spider)
  • process_spider_exception(response, exception, spider)
  • process_start_requests(start_requests, spider)

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

process_spider_input(response, spider)

参数:

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

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

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

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

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

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

process_spider_output(response, result, spider)

参数:

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

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

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

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

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

process_spider_exception(response, exception, spider)

参数:

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

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

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

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

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

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

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

process_start_requests(start_requests, spider)

参数:

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

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

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

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

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

参考

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

小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware的更多相关文章

  1. 小白学 Python 爬虫(38):爬虫框架 Scrapy 入门基础(六) Item Pipeline

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  2. 小白学 Python 爬虫(41):爬虫框架 Scrapy 入门基础(八)对接 Splash 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

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

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

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

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

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

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  6. 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  7. 小白学 Python 数据分析(6):Pandas (五)基础操作(2)数据选择

    人生苦短,我用 Python 前文传送门: 小白学 Python 数据分析(1):数据分析基础 小白学 Python 数据分析(2):Pandas (一)概述 小白学 Python 数据分析(3):P ...

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

    人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...

  9. 小白学 Python 数据分析(1):数据分析基础

    各位同学好,小编接下来为大家分享一些有关 Python 数据分析方面的内容,希望大家能够喜欢. 人工植入广告: PS:小编最近两天偷了点懒,好久没有发原创了,最近是在 CSDN 开通了一个付费专栏,用 ...

随机推荐

  1. Laravel获取所有的数据库表及结构

    遇到一个需求,需要修改数据库中所有包含email的字段的表,要把里面的长度改为128位.Laravel获取所有的表,然后循环判断表里面有没有email这个字段.代码如下: use Illuminate ...

  2. CSS画矩形、圆、半圆、弧形、半圆、小三角、疑问框

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  3. 数据存储在哪里? Java是值传递还是引用传递?

    寄存器 : 最快的存储区,位于处理器中,寄存器会按需求自行分配空间,java不能控制寄存器,所以在程序中感觉不到它的存在 栈(stack) : 位于RAM(内存)中,速度仅次于寄存器,存储对象的引用( ...

  4. Bi-LSTM-CRF for Sequence Labeling

    做了一段时间的Sequence Labeling的工作,发现在NER任务上面,很多论文都采用LSTM-CRFs的结构.CRF在最后一层应用进来可以考虑到概率最大的最优label路径,可以提高指标. 一 ...

  5. 获取exe和dll里面的资源

    有时候需要仿照另一个程序实现一些对话框,比较笨的办法是打开那个程序,照着样子自己在VC里面画啊画.这样的效率实在有点低. 现在有很多工具可以从exe和dll里面取出图片.图片.字符串.对话框等资源.比 ...

  6. Python--day37--多进程

    1,创建多进程(父进程和子进程) import os import time #多进程都要导入multiprocessing from multiprocessing import Process d ...

  7. linux scull 中的设备注册

    在内部, scull 使用一个 struct scull_dev 类型的结构表示每个设备. 这个结构定义为: struct scull_dev { struct scull_qset *data;  ...

  8. [Ramda] Handle Errors in Ramda Pipelines with tryCatch

    Handling your logic with composable functions makes your code declarative, leading to code that's ea ...

  9. C# double 好用的扩展

    在很多代码需要使用数学计算,在用到 double 很难直接判断一个值是 0 或者 1 ,判断两个值相等. 本文提供一个数学扩展,让大家可以简单使用到 double 判断 在开始看本文之前,希望大家是知 ...

  10. linux poll 和 select

    使用非阻塞 I/O 的应用程序常常使用 poll, select, 和 epoll 系统调用. poll, select 和 epoll 本质上有相同的功能: 每个允许一个进程来决定它是否可读或者写一 ...