前言
大部分人的身上陌粹,有一種近乎無解的矛盾——
想要養(yǎng)成早起的習(xí)慣,卻一不小心刷手機(jī)到凌晨兩點(diǎn)福压;
看到一篇干貨文章掏秩,第一反應(yīng)是加收藏夾下次再看(收藏從未停止或舞,學(xué)習(xí)從未開始。/ 收藏==學(xué)會)蒙幻;
想要瘦身塑形映凳,卻在深夜破功:“吃飽了才有力氣減肥”;
看到一門不錯的課程邮破,卻還是告訴自己有時間了再學(xué)......
Spider Middleware的使用方法
Spider Middleware是介入到Scrapy的Spider處理機(jī)制的鉤子框架诈豌。
當(dāng)Downloader生成Response之后,Response會被發(fā)送給Spider抒和,在發(fā)送Spider之前矫渔,Response會首先經(jīng)過Spider Middleware處理,當(dāng)Spider處理生成Item和Request之后摧莽,Item和Request還會經(jīng)過Spider Middleware的處理庙洼。
Spider Middleware有如下三個作用:
- 我們可以在Downloader生成Response發(fā)送給Spider之前,也就是Response發(fā)送給Spider之前對Response進(jìn)行處理范嘱。
- 我們可以Spider生成Request發(fā)送給Scheduler之前眷蜓,也就是Request發(fā)送給Scheduler之前對Request進(jìn)行處理纸兔。
- 我們可以在Spider生成Item發(fā)送給Item Pipeline之前乌叶,也就是Item發(fā)送給Item Pipeline之前對Item進(jìn)行處理麻车。
使用說明
需要說明的是Scrapy其實(shí)已經(jīng)提供了許多Spider Middleware,它們被SPIDER_MIDDLEWARES_BASE這個變量所定義受裹。
SPIDER_MIDDLEWARE_BASE變量內(nèi)容如下:
{
'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設(shè)置當(dāng)中,該設(shè)置會和Scrapy中SPIDER_MIDDLEWARES_BASE定義的Spider Middleware合并棉饶。然后根據(jù)鍵值的數(shù)字優(yōu)先級排序厦章,得到一個有序列表。第一個Middleware是最靠近引擎的照藻,最后一個MIddleware是最靠近Spider的袜啃。
核心方法
Scrapy內(nèi)置的Spider Middleware為Spider提供了基礎(chǔ)功能。如果我們想要拓展其功能幸缕,只需要實(shí)現(xiàn)某個方法即可群发。
每個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)
process_spider_input(response, spider)
當(dāng)Response通過Spider Middleware時发乔,該方法被調(diào)用熟妓,處理該Response。
方法的參數(shù)有兩個:
- response:即Response對象栏尚,即被處理的Response
- Spider:即Spider對象起愈,即該Response對應(yīng)的Spider
process_spider_input()應(yīng)該返回None或拋出異常。
- 如果返回None,Scrapy將繼續(xù)處理該Response抬虽,調(diào)用其他的Spider Middleware直到Spider處理該Response官觅。
- 如果拋出一個異常,Scrapy將不會調(diào)用任何其他Spider Middleware的process_spider_input()的方法阐污,并調(diào)用Request的errback()方法缰猴。errback()的輸出將會以另一個方向被重新輸入到中間件中,使用process_spider-output()方法來處理疤剑,當(dāng)其拋出異常時,則調(diào)用process_spider_exception()來處理闷堡。
process_spider_output(response, result, spider)
當(dāng)Spider處理Response返回結(jié)果時隘膘,該方法被調(diào)用。
方法的參數(shù)有三個:
- response杠览,即Response對象弯菊,即生成該輸出的Response;
- result踱阿,包含Request或Item對象的可迭代對象管钳,即Spider返回的結(jié)果;
- spider软舌,即Spider對象才漆,即其結(jié)果對應(yīng)的Spider。
process_spider_output()必須返回包含Request或Item對象的可迭代對象佛点。
process_spider_exception(response, exception, spider)
當(dāng)Spider或Spider Middleware的process_spider_input()方法拋出異常時醇滥,該方法被調(diào)用。
方法的參數(shù)有三個:
- response超营,即Response對象鸳玩,即異常被拋出時被處理的Response。
- exception演闭,即Exception對象不跟,被拋出的異常。
- spider米碰,即Spider對象窝革,即拋出異常的Spider
process_spider_exception()要么返回None,要么返回一個包含Response或Item對象的可迭代對象见间。
- 如果其返回None聊闯,Scrapy將繼續(xù)處理該異常,調(diào)用其他Spider Middleware中的process_spider_exception()方法米诉,直到所有的Spider Middleware被調(diào)用菱蔬。
- 如果返回一個可迭代對象,則其他的Spider Middleware的process_spider_output()方法被調(diào)用,其他的process_spider_exception()將不會被調(diào)用拴泌。
process_start_requests(start_requests, spider)
該方法以Spider啟動的Request為參數(shù)被調(diào)用魏身,執(zhí)行的過程類似于process_spider_output(),只不過其他沒有相關(guān)聯(lián)的Response并且必須返回Request蚪腐。
方法的參數(shù)有兩個:
- start_requests箭昵,即包含Request的可迭代對象,即Start Requests
- spider回季,即Spider對象家制,即Start Requests所屬的Spider
其必須返回一個包含Request對象的可迭代對象。
開啟Spider Middleware
每當(dāng)我們創(chuàng)建一個新的項目的時候泡一,就會生成一個middlewares.py
的文件颤殴,在這個文件中有一個類:MiddletestSpiderMiddleware
,這個類與我們創(chuàng)建的項目名相關(guān)鼻忠,我創(chuàng)建的項目名為``Middletest`涵但。因此,當(dāng)我們修改這個項目名的時候帖蔓,這個類名也要跟著修改矮瘟。
在這個類中,里面就有我們上面所描述的四個核心方法塑娇。
我們要開啟這個Spider Middleware澈侠,可以到settings.py里面去開啟:
# Enable or disable spider middlewares
# See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
SPIDER_MIDDLEWARES = {
'middletest.middlewares.MiddletestSpiderMiddleware': 543,
}
只需要取消注釋即可。
最后
沒有什么事情是可以一蹴而就的埋酬,生活如此埋涧,學(xué)習(xí)亦是如此!
因此奇瘦,哪里會有什么三天速成棘催,七天速成的說法呢?
唯有堅持耳标,方能成功醇坝!
啃書君說:
文章的每一個字都是我用心敲出來的,只希望對得起每一位關(guān)注我的人次坡。在文章末尾點(diǎn)【贊】呼猪,讓我知道,你們也在為自己的學(xué)習(xí)拼搏和努力砸琅。
路漫漫其修遠(yuǎn)兮宋距,吾將上下而求索。
我是啃書君症脂,一個專注于學(xué)習(xí)的人谚赎,你懂的越多淫僻,你不懂的越多。更多精彩內(nèi)容壶唤,我們下期再見雳灵!