Scrapy框架的架構原理解析
阿新 • • 發佈:2020-09-13
# 爬蟲框架——Scrapy
如果你對爬蟲的基礎知識有了一定了解的話,那麼是時候該瞭解一下爬蟲框架了。**那麼為什麼要使用爬蟲框架?**
- 學習框架的根本是學習一種程式設計思想,而不應該僅僅侷限於是如何使用它。從瞭解到掌握一種框架,其實是對一種思想理解的過程。
- 框架也給我們的開發帶來了極大的方便。許多條條框框都已經是寫好了的,並不需要我們重複造輪子,我們只需要根據自己的需求定製自己要實現的功能就好了,大大減少了工作量。
- 參考並學習優秀的框架程式碼,提升程式設計程式碼能力
## scrapy框架的介紹
比較流行的爬蟲的框架有`scrapy`和`pyspider`,但是被大家所鍾愛的我想非`scrapy`莫屬了。`scrapy`是一個開源的高階爬蟲框架,我們可以稱它為"scrapy語言"。它使用`python`編寫,用於爬取網頁,提取結構性資料,並可將抓取得結構性資料較好的應用於資料分析和資料探勘。`scrapy`有以下的一些特點:
- `scrapy`基於事件的機制,利用`twisted`的設計實現了**非阻塞**的非同步操作。這相比於傳統的阻塞式請求,極大的提高了CPU的使用率,以及爬取效率。
- 配置簡單,可以簡單地通過設定一行程式碼實現複雜功能。
- 可拓展,外掛豐富,比如分散式scrapy + redis、爬蟲視覺化等外掛。
- 解析方便易於使用,scrapy封裝了xpath等解析器,提供了更方便,更高階的selector構造器,可以有效的處理破損的HTML程式碼和編碼。
## scrapy的架構
[![img](https://img2020.cnblogs.com/blog/1880551/202009/1880551-20200909111651246-723329047.png)](https://img2020.cnblogs.com/blog/1880551/202009/1880551-20200909111651246-723329047.png)
## 元件
**引擎(Engine)**
引擎負責控制資料流在系統中所有元件中流動,並在相應動作發生時觸發事件。 詳細內容檢視下面的資料流`(Data Flow)`部分。
**排程器(Scheduler)**
排程器從引擎接受`request`並將他們入隊,以便之後引擎請求他們時提供給引擎。
**下載器(Downloader)**
下載器負責獲取頁面資料並提供給引擎,而後提供給`spider`。
**爬蟲(Spiders)**
`Spider`是`Scrapy`使用者編寫用於分析`response`並提取`item`(即獲取到的item)或額外跟進的URL的類。 每個`spider`負責處理一個特定(或一些)網站。
**專案管道(Item Pipeline)**
`Item Pipeline`負責處理被`spider`提取出來的`item`。典型的處理有清理、 驗證及持久化(例如存取到資料庫中)。
**下載器中介軟體(Downloader middlewares)**
下載器中介軟體是在引擎及下載器之間的特定鉤子`(specific hook)`,處理`Downloader`傳遞給引擎的`response`。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件`Scrapy`功能。
**爬蟲中介軟體(Spider middlewares)**
`Spider中介軟體`是在引擎及Spider之間的特定鉤子`(specific hook)`,處理`spider`的輸入(response)和輸出(items及requests)。 其提供了一個簡便的機制,通過插入自定義程式碼來擴充套件Scrapy功能。
## 資料流過程
1. 引擎開啟一個網站`(open a domain)`,找到處理該網站的`Spider`並向該`spider`請求第一個要爬取的URL(s)。
2. 引擎從`Spider`中獲取到第一個要爬取的URL並在排程器`(Scheduler)`以`Request`排程。
3. 引擎向排程器請求下一個要爬取的URL。
4. 排程器返回下一個要爬取的URL給引擎,引擎將URL通過下載中介軟體(請求`(request)`方向)轉發給下載器`(Downloader)`。
5. 一旦頁面下載完畢,下載器生成一個該頁面的`Response`,並將其通過下載中介軟體(返回`(response)`方向)傳送給引擎。
6. 引擎從下載器中接收到`Response`並通過`Spider中介軟體`(輸入方向)傳送給Spider處理。
7. `Spider`處理`Response`並返回爬取到的`Item`及(跟進的)新的Request給引擎。
8. 引擎將(Spider返回的)爬取到的Item給`Item Pipeline`,將(Spider返回的)Request給排程器。
9. (從第二步)重複直到排程器中沒有更多地`request`,引擎關閉該網站。
## scrapy和requests+bs用哪個好?
這個根據自己方便來,requests + beautifulsoup當然可以了,requests + 任何解器式都行,都是非常好的合作。這樣用的有點是我們可以靈活地寫我們自己的程式碼,不必拘泥於固定模式。對於使用固定的框架有時候不一定用起來方便,比如scrapy對於反反爬處理並沒有很完善,好多時候也要自己來解決。
但是對於一些中小型的爬蟲任務來講,`scrapy`確實是非常好的選擇,它避免了我們來寫一些重複的程式碼,並且有著出色的效能。我們自己寫程式碼的時候,比如為了提高爬取效率,每次都自己碼多執行緒或非同步等程式碼,大大浪費了開發時間。這時候使用已經寫好的框架是再好不過的選擇了,我們只要簡單的寫寫解析規則和`pipeline`就好了。那麼具體哪些是需要我們做的呢?看看下面這個圖就明白了。
![img](https://img2020.cnblogs.com/blog/1880551/202009/1880551-20200909111332113-19765693