scrapy架構(gòu)詳解

Scrapy架構(gòu)概覽

要探究清楚Spider Middleware呻右,首先得對Scrapy框架的整體架構(gòu)有個大致的認(rèn)識肆捕,如下圖所示:


image.png

1己儒,組件(Components)

Scrapy 引擎(Engine)
引擎負(fù)責(zé)控制數(shù)據(jù)流在系統(tǒng)中所有組件中流動客峭,并在相應(yīng)動作發(fā)生時觸發(fā)事件示血。 詳細(xì)內(nèi)容查看下面的數(shù)據(jù)流(Data Flow)部分。

調(diào)度器(Scheduler)

調(diào)度器從引擎接受request并將他們?nèi)腙?duì)亚亲,以便之后引擎請求他們時提供給引擎。

下載器(Downloader)

下載器負(fù)責(zé)獲取頁面數(shù)據(jù)并提供給引擎腐缤,而后提供給spider捌归。

Spiders

Spider是Scrapy用戶編寫用于分析response并提取item(即獲取到的item)或額外跟進(jìn)的URL的類。 每個spider負(fù)責(zé)處理一個特定(或一些)網(wǎng)站岭粤,我們前面幾篇文章中惜索,通過Scrapy框架實(shí)現(xiàn)的爬蟲例子都是在Spiders這個組件中實(shí)現(xiàn)。 更多內(nèi)容請看 Spiders 剃浇。

管道(Item Pipeline)

Item Pipeline負(fù)責(zé)處理被spider提取出來的item巾兆。典型的處理有清理、 驗(yàn)證及持久化(例如存取到數(shù)據(jù)庫中)虎囚。 更多內(nèi)容查看 Item Pipeline 角塑。

下載器中間件(Downloader Middlewares)

下載器中間件是在引擎及下載器之間的特定鉤子(specific hook),處理Downloader傳遞給引擎的response淘讥,以及引擎?zhèn)鬟f給Downloader的request,(介于reuqest和response之間) 其提供了一個簡便的機(jī)制圃伶,通過插入自定義代碼來擴(kuò)展Scrapy功能。更多內(nèi)容請看 Downloader Middleware 。

Spider中間件(Spider Middlewares)

Spider中間件是在引擎及Spider之間的特定鉤子(specific hook)窒朋,處理spider的輸入(response)和輸出(items及requests)搀罢。 其提供了一個簡便的機(jī)制,通過插入自定義代碼來擴(kuò)展Scrapy功能侥猩。更多內(nèi)容請看 Spider Middleware 榔至。

2,數(shù)據(jù)流(Data flow)

Scrapy中的數(shù)據(jù)流由執(zhí)行引擎控制欺劳,其過程如下:

1唧取,引擎從Spiders中獲取到最初的要爬取的請求(Requests)。
2杰标,引擎安排請求(Requests)到調(diào)度器中兵怯,并向調(diào)度器請求下一個要爬取的請求(Requests)。
3腔剂,調(diào)度器返回下一個要爬取的請求(Requests)給引擎媒区。
4,引擎將上步中得到的請求(Requests)通過下載器中間件(Downloader Middlewares)發(fā)送給下載器(Downloader )掸犬,這個過程中下載器中間件(Downloader Middlewares)中的process_request()函數(shù)會被調(diào)用到袜漩。
5,一旦頁面下載完畢湾碎,下載器生成一個該頁面的Response宙攻,并將其通過下載中間件(Downloader Middlewares)發(fā)送給引擎,這個過程中下載器中間件(Downloader Middlewares)中的process_response()函數(shù)會被調(diào)用到介褥。
6座掘,引擎從下載器中得到上步中的Response并通過Spider中間件(Spider Middlewares)發(fā)送給Spider處理,這個過程中Spider中間件(Spider Middlewares)中的process_spider_input()函數(shù)會被調(diào)用到柔滔。
7溢陪,Spider處理Response并通過Spider中間件(Spider Middlewares)返回爬取到的Item及(跟進(jìn)的)新的Request給引擎,這個過程中Spider中間件(Spider Middlewares)的process_spider_output()函數(shù)會被調(diào)用到睛廊。
8形真,引擎將上步中Spider處理的其爬取到的Item給Item 管道(Pipeline),將Spider處理的Request發(fā)送給調(diào)度器超全,并向調(diào)度器請求可能存在的下一個要爬取的請求(Requests)咆霜。
9,(從第二步)重復(fù)直到調(diào)度器中沒有更多的請求(Requests)嘶朱。

二蛾坯,Spider中間件(Spider Middlewares)

Spider中間件是介入到Scrapy中的spider處理機(jī)制的鉤子框架,可以插入自定義功能來處理發(fā)送給 Spiders 的response疏遏,以及spider產(chǎn)生的item和request偿衰。

1挂疆,激活Spider中間件(Spider Middlewares)
要啟用Spider中間件(Spider Middlewares),可以將其加入到 SPIDER_MIDDLEWARES 設(shè)置中下翎。 該設(shè)置是一個字典缤言,鍵為中間件的路徑,值為中間件的順序(order)视事。

樣例:

SPIDER_MIDDLEWARES = {
'myproject.middlewares.CustomSpiderMiddleware': 543,
}
SPIDER_MIDDLEWARES 設(shè)置會與Scrapy定義的 SPIDER_MIDDLEWARES_BASE 設(shè)置合并(但不是覆蓋)胆萧, 而后根據(jù)順序(order)進(jìn)行排序,最后得到啟用中間件的有序列表: 第一個中間件是最靠近引擎的俐东,最后一個中間件是最靠近spider的跌穗。

關(guān)于如何分配中間件的順序請查看 SPIDER_MIDDLEWARES_BASE 設(shè)置,而后根據(jù)您想要放置中間件的位置選擇一個值虏辫。 由于每個中間件執(zhí)行不同的動作蚌吸,您的中間件可能會依賴于之前(或者之后)執(zhí)行的中間件,因此順序是很重要的砌庄。

如果您想禁止內(nèi)置的(在 SPIDER_MIDDLEWARES_BASE 中設(shè)置并默認(rèn)啟用的)中間件羹唠, 您必須在項(xiàng)目的 SPIDER_MIDDLEWARES設(shè)置中定義該中間件,并將其值賦為 None 娄昆。 例如佩微,如果您想要關(guān)閉off-site中間件:

SPIDER_MIDDLEWARES = {
'myproject.middlewares.CustomSpiderMiddleware': 543,
'scrapy.contrib.spidermiddleware.offsite.OffsiteMiddleware': None,
}

最后,請注意萌焰,有些中間件需要通過特定的設(shè)置來啟用哺眯。更多內(nèi)容請查看相關(guān)中間件文檔。

2扒俯,編寫自己的spider中間件
編寫spider中間件十分簡單奶卓。每個中間件組件是一個定義了以下一個或多個方法的Python類:
class scrapy.contrib.spidermiddleware.SpiderMiddleware
process_spider_input(response, spider)
當(dāng)response通過spider中間件時,該方法被調(diào)用撼玄,處理該response夺姑。

process_spider_input() 應(yīng)該返回 None 或者拋出一個異常(exception)。

如果其返回 None 互纯,Scrapy將會繼續(xù)處理該response瑟幕,調(diào)用所有其他的中間件直到spider處理該response磕蒲。

如果其拋出一個異常(exception)留潦,Scrapy將不會調(diào)用任何其他中間件的 process_spider_input() 方法,并調(diào)用request的errback辣往。 errback的輸出將會以另一個方向被重新輸入到中間件鏈中兔院,使用 process_spider_output() 方法來處理,當(dāng)其拋出異常時則帶調(diào)用process_spider_exception() 站削。

參數(shù):
response (Response 對象) – 被處理的response
spider (Spider 對象) – 該response對應(yīng)的spider

process_spider_output(response, result, spider)
當(dāng)Spider處理response返回result時坊萝,該方法被調(diào)用。

process_spider_output() 必須返回包含 Request 或 Item 對象的可迭代對象(iterable)。

參數(shù):
response (Response 對象) – 生成該輸出的response
result (包含 Request 或 Item 對象的可迭代對象(iterable)) – spider返回的result
spider (Spider 對象) – 其結(jié)果被處理的spider

process_spider_exception(response, exception, spider)
當(dāng)spider或(其他spider中間件的) process_spider_input() 拋出異常時十偶, 該方法被調(diào)用菩鲜。

process_spider_exception() 必須要么返回 None , 要么返回一個包含 Response 或 Item 對象的可迭代對象(iterable)惦积。

如果其返回 None 接校,Scrapy將繼續(xù)處理該異常,調(diào)用中間件鏈中的其他中間件的 process_spider_exception() 方法狮崩,直到所有中間件都被調(diào)用蛛勉,該異常到達(dá)引擎(異常將被記錄并被忽略)。

如果其返回一個可迭代對象睦柴,則中間件鏈的 process_spider_output() 方法被調(diào)用诽凌, 其他的 process_spider_exception() 將不會被調(diào)用。

參數(shù):
response (Response 對象) – 異常被拋出時被處理的response
exception (Exception 對象) – 被跑出的異常
spider (Spider 對象) – 拋出該異常的spider

process_start_requests(start_requests, spider)
0.15 新版功能.

該方法以spider 啟動的request為參數(shù)被調(diào)用坦敌,執(zhí)行的過程類似于 process_spider_output() 侣诵,只不過其沒有相關(guān)聯(lián)的response并且必須返回request(不是item)。

其接受一個可迭代的對象(start_requests 參數(shù))且必須返回另一個包含 Request 對象的可迭代對象恬试。

注解
當(dāng)在您的spider中間件實(shí)現(xiàn)該方法時窝趣, 您必須返回一個可迭代對象(類似于參數(shù)start_requests)且不要遍歷所有的 start_requests。 該迭代器會很大(甚至是無限)训柴,進(jìn)而導(dǎo)致內(nèi)存溢出哑舒。 Scrapy引擎在其具有能力處理start request時將會拉起request, 因此start request迭代器會變得無限幻馁,而由其他參數(shù)來停止spider( 例如時間限制或者item/page記數(shù))洗鸵。

參數(shù):
start_requests (包含 Request 的可迭代對象) – start requests
spider (Spider 對象) – start requests所屬的spider

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市仗嗦,隨后出現(xiàn)的幾起案子膘滨,更是在濱河造成了極大的恐慌,老刑警劉巖稀拐,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件火邓,死亡現(xiàn)場離奇詭異,居然都是意外死亡德撬,警方通過查閱死者的電腦和手機(jī)铲咨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蜓洪,“玉大人纤勒,你說我怎么就攤上這事÷√矗” “怎么了摇天?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵粹湃,是天一觀的道長。 經(jīng)常有香客問我泉坐,道長为鳄,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任腕让,我火速辦了婚禮济赎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘记某。我一直安慰自己司训,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布液南。 她就那樣靜靜地躺著壳猜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滑凉。 梳的紋絲不亂的頭發(fā)上统扳,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天,我揣著相機(jī)與錄音畅姊,去河邊找鬼咒钟。 笑死,一個胖子當(dāng)著我的面吹牛若未,可吹牛的內(nèi)容都是我干的朱嘴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼粗合,長吁一口氣:“原來是場噩夢啊……” “哼萍嬉!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起隙疚,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤壤追,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后供屉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體行冰,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年伶丐,在試婚紗的時候發(fā)現(xiàn)自己被綠了悼做。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡撵割,死狀恐怖贿堰,靈堂內(nèi)的尸體忽然破棺而出辙芍,到底是詐尸還是另有隱情啡彬,我是刑警寧澤羹与,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站庶灿,受9級特大地震影響纵搁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜往踢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一腾誉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧峻呕,春花似錦利职、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至讯私,卻和暖如春热押,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背斤寇。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工桶癣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人娘锁。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓牙寞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親莫秆。 傳聞我的和親對象是個殘疾皇子碎税,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348