Scrapy是一個(gè)為了爬取網(wǎng)站數(shù)據(jù)、提取結(jié)構(gòu)化數(shù)據(jù)而編寫的爬蟲應(yīng)用框架。Scrapy內(nèi)部實(shí)現(xiàn)了包括并發(fā)請求、免登錄、URL去重等很多復(fù)雜操作,用戶不需要明白Scrapy內(nèi)部具體的爬取策略,只需要根據(jù)自己的需要,編寫小部分的代碼,就能抓取到所需要的數(shù)據(jù)。Scrapy主要由5個(gè)組成部分,若需要實(shí)現(xiàn)更多功能,Scrapy還提供了多種中間件。這五個(gè)模塊及中間件的功能如下:
Scrapy Engine(Scrapy引擎)
Scrapy Engine是用來控制整個(gè)爬蟲系統(tǒng)的數(shù)據(jù)處理流程,并進(jìn)行不同事務(wù)觸發(fā)。Scheduler(調(diào)度器)
Scheduler維護(hù)著待爬取的URL隊(duì)列,當(dāng)調(diào)度程序從Scrapy Engine接受到請求時(shí),會從待爬取的URL隊(duì)列中取出下一個(gè)URL返還給他們。Downloader(下載器)
Downloader從Scrapy Engine那里得到需要下載的URL,并向該網(wǎng)址發(fā)送網(wǎng)絡(luò)請求進(jìn)行頁面網(wǎng)頁,最后再將網(wǎng)頁內(nèi)容傳遞到Spiders來處理。如果需要定制更復(fù)雜的網(wǎng)絡(luò)請求,可以通過Downloader中間件來實(shí)現(xiàn),Spiders(蜘蛛)
Spiders是用戶需要編輯的代碼的部分。用戶通過編寫spider.py這個(gè)類實(shí)現(xiàn)指定要爬取的網(wǎng)站地址、定義網(wǎng)址過濾規(guī)則、解析目標(biāo)數(shù)據(jù)等。 Spider發(fā)出請求,并處理Scrapy Engine返回給它下載器響應(yīng)數(shù)據(jù),把解析到的數(shù)據(jù)以item的形式傳遞給Item Pipeline,把解析到的鏈接傳遞給Scheduler。Item Pipeline(項(xiàng)目管道)
Item 定義了爬蟲要抓取的數(shù)據(jù)的字段,類似于關(guān)系型數(shù)據(jù)庫中表的字段名,用戶編寫item.py文件來實(shí)現(xiàn)這一功能。Pipeline主要負(fù)責(zé)處理Spider從網(wǎng)頁中抽取的item,對item進(jìn)行清洗、驗(yàn)證,并且將數(shù)據(jù)持久化,如將數(shù)據(jù)存入數(shù)據(jù)庫或者文件。用戶編寫pipeline.py實(shí)現(xiàn)這一功能。Downloader middlewares(下載器中間件)
Downloader middlewares是位于Scrapy Engine和Downloader之間的鉤子框架,主要是處理Scrapy Engine與Downloader之間的請求及響應(yīng)。可以代替接收請求、處理數(shù)據(jù)的下載以及將結(jié)果響應(yīng)給Scrapy Engine。Spider middlewares(蜘蛛中間件)
Spider middlewares是介于Scrapy Engine和Spiders之間的鉤子框架,主要是處理Spiders的響應(yīng)輸入和請求輸出??梢圆迦胱远x的代碼來處理發(fā)送給Spiders的請求和返回Spider獲取的響應(yīng)內(nèi)容和項(xiàng)目。
Scrapy 使用 Twisted 這個(gè)異步網(wǎng)絡(luò)庫來處理網(wǎng)絡(luò)通訊,架構(gòu)清晰,可以靈活的完成各種需求。整體架構(gòu)如下圖所示:

圖中綠色線條表示數(shù)據(jù)流向,首先從初始 URL 開始,Scheduler 會將其交給 Downloader,Downloader向網(wǎng)絡(luò)服務(wù)器發(fā)送服務(wù)請求進(jìn)行下載,得到響應(yīng)后將下載的數(shù)據(jù)交給Spider,Spider會對網(wǎng)頁進(jìn)行分析,分析出來的結(jié)果有兩種:一種是需要進(jìn)一步抓取的鏈接,這些鏈接會被傳回 Scheduler;另一種是需要保存的數(shù)據(jù),它們則被送到 Item Pipeline,Item會定義數(shù)據(jù)格式, 最后由Pipeline對數(shù)據(jù)進(jìn)行清洗、去重等處理后存儲到文件或數(shù)據(jù)庫。
Scrapy數(shù)據(jù)流是由執(zhí)行的核心引擎(engine)控制,流程是這樣的:
引擎打開一個(gè)域名,蜘蛛處理這個(gè)域名,并讓蜘蛛獲取第一個(gè)爬取的URL。
引擎從蜘蛛那獲取第一個(gè)需要爬取的URL,然后作為請求在調(diào)度中進(jìn)行調(diào)度。
引擎從調(diào)度那獲取接下來進(jìn)行爬取的頁面。
調(diào)度將下一個(gè)爬取的URL返回給引擎,引擎將他們通過下載中間件發(fā)送到下載器。
當(dāng)網(wǎng)頁被下載器下載完成以后,響應(yīng)內(nèi)容通過下載中間件被發(fā)送到引擎。
引擎收到下載器的響應(yīng)并將它通過蜘蛛中間件發(fā)送到蜘蛛進(jìn)行處理。
蜘蛛處理響應(yīng)并返回爬取到的item,然后給引擎發(fā)送新的請求。
引擎發(fā)送處理后的item到項(xiàng)目管道,然后把處理結(jié)果返回給調(diào)度器,調(diào)度器計(jì)劃處理下一個(gè)請求抓取。
系統(tǒng)重復(fù)2-9的操作,直到調(diào)度中沒有請求,然后斷開引擎與域之間的聯(lián)系。