第3章 Scrapy架構介紹
Scrapy是一個為了爬取網站資訊,提取結構性資料而編寫的應用架構。Scrapy用途廣泛,可用于資料挖掘、監測和自動化測試等。
3.1 網絡爬蟲原理
網絡爬蟲的英文為Web Spider,又稱做網絡蜘蛛或網絡機器人。如果把網際網路比喻成一張巨大的蜘蛛網,資料便是存放于蜘蛛網中的各個節點,爬蟲就是網中爬行的蜘蛛,沿着網絡抓取自己的獵物(資料)。
網絡爬蟲簡單來說就是一種按照一定規則,自動地抓取網際網路中資訊的程式或腳本。
3.1.1 爬蟲執行的流程
我們知道,網絡爬蟲執行的基本流程是:模拟使用者使用浏覽器向網站發送請求,網站響應請求後将網頁文檔發送過來,爬蟲對網頁做資訊提取和存儲。具體流程如圖3-1所示。

圖3-1 爬蟲執行流程
圖3-1中的爬蟲執行流程,介紹如下:
(1)發送請求。
爬蟲設定一個URL,模拟浏覽器使用HTTP協定向網站伺服器發送通路請求。
(2)擷取HTML文檔。
伺服器接收到請求後,将HTML文檔(或者圖檔、視訊等其他資源)發送給爬蟲。
(3)抽取資料。
爬蟲使用XPath或BeautifulSoup從HTML文檔中抽取出有用的資料。
(4)儲存資料。
将抽取到的資料儲存到檔案(CSV、JSON、TXT等)或資料庫(MySQL、MongoDB等)中,實作資料的持久化存儲。
上面流程中的每一步,看似簡單,但實作起來着實不易。如何僞裝成浏覽器?如何構造一個HTTP請求發送給網站伺服器?如何擷取網站伺服器發送的HTML文檔?如何抽取HTML資料?如何将每一個步驟關聯起來?種種問題,在學習Scrapy爬蟲架構後,都能輕松解決。還等什麼呢?下面開始我們的Scrapy學習之旅吧!
3.2 Scrapy架構結構及執行流程
Scrapy架構結構和流程設計遵循網絡爬蟲的基本原理。通過元件封裝不同的功能子產品;通過請求和響應類封裝資料流;通過引擎指揮整個系統協調運作。
3.2.1 Scrapy架構結構
了解了HTTP和爬蟲的基本原理,就不難了解Scrapy的架構結構了。如圖3-2所示為Scrapy的架構結構,包含了不同功能的元件、系統中發生的資料流及執行流程。
1.元件
下面簡單介紹一下Scrapy架構結構中包含的元件。
-
引擎(Engine)
引擎猶如總指揮,是整個系統的“大腦”,指揮其他元件協同工作。
-
排程器(Scheduler)
排程器接收引擎發過來的請求,按照先後順序,壓入隊列中,同時去除重複的請求。
-
下載下傳器(Downloader)
下載下傳器用于下載下傳網頁内容,并将網頁内容傳回給爬蟲(Scrapy下載下傳器是建立在twisted這個高效的異步模型上的)。
-
爬蟲(Spiders)
爬蟲作為最核心的元件,用于從特定的網頁中提取需要的資訊,即所謂的實體(Item)。使用者也可以從中提取對外連結接,讓Scrapy繼續抓取下一個頁面。
圖3-2 Scrapy架構結構
-
項目管道(Item Pipelines)
項目管道負責處理爬蟲從網頁中抽取的實體。主要的功能是持久化實體、驗證明體的有效性、清除不需要的資訊等。
-
下載下傳器中間件(Downloader Middlewares)
下載下傳器中間件介于引擎和下載下傳器之間,主要處理Scrapy引擎與下載下傳器之間的請求及響應。
-
爬蟲中間件(Spider Middlewares)
爬蟲中間件介于引擎和爬蟲之間,主要工作是處理爬蟲的響應輸入和請求輸出。
2.資料流
Scrapy架構結構中傳遞和處理的資料主要有以下3種:
- 向網站伺服器發送的請求資料(請求的内容見2.1.3節);
- 網站伺服器傳回的響應資料(響應的内容見2.1.4節);
-
解析後的結構資料(類似于字典)。
Scrapy中定義的Request和Response類,用于儲存請求和響應資料;Item類儲存解析後的結構資料。它們分别對應于圖3-2中辨別的Requests、Response和Items。
3.2.2 Scrapy執行流程
下面從資料流的角度介紹Scrapy架構的執行流程。
圖3-2中第①、②、③、④步,執行的是HTTP請求,傳遞和處理的是向網站伺服器發送的請求資料。
第①步:爬蟲(Spider)使用URL(要爬取頁面的網址)構造一個請求(Request)對象,送出給引擎(Engine)。如果請求要僞裝成浏覽器,或者設定代理IP,可以先在爬蟲中間件中設定,再發送給引擎。
第②步:引擎将請求安排給排程器,排程器根據請求的優先級确定執行順序。
第③步:引擎從排程器擷取即将要執行的請求。
第④步:引擎通過下載下傳器中間件,将請求發送給下載下傳器下載下傳頁面。
圖3-2中第⑤、⑥、⑦、⑧步,執行的是HTTP響應,傳遞和處理的是網站伺服器傳回的響應資料。
第⑤步:頁面完成下載下傳後,下載下傳器會生成一個響應(Response)對象并将其發送給引擎。下載下傳後的資料會儲存于響應對象中。
第⑥步:引擎接收來自下載下傳器的響應對象後,通過爬蟲中間件,将其發送給爬蟲(Spider)進行處理。
第⑦步:爬蟲将抽取到的一條資料實體(Item)和新的請求(如下一頁的連結)發送給引擎。
第⑧步:引擎将從爬蟲擷取到的Item發送給項目管道(Item Pipelines),項目管道實作資料持久化等功能。同時将新的請求發送給排程器,再從第②步開始重複執行,直到排程器中沒有更多的請求,引擎關閉該網站。
3.3 Scrapy安裝
Scrapy作為一個強大的爬蟲架構,需要依賴于很多庫。幸運的是,前面我們安裝了Anaconda,它已經幫我們安裝好了Scrapy所有的依賴庫。是以,無論在哪個作業系統,安裝Scrapy就非常簡單了。
3.3.1 使用pip安裝Scrapy
這裡還是使用pip安裝Scrapy架構,指令如下:
>pip install scrapy
3.3.2 常見安裝錯誤
因為系統環境的差異,在安裝Scrapy時,有時會出現各種意想不到的錯誤。例如,使用pip安裝Scrapy時遇到Microsoft Visual C++14.0 is required錯誤,如圖3-3所示。
圖3-3 Scrapy安裝時出現的錯誤
解決方法1
如果使用pip安裝失敗,可以試着使用Conda安裝Scrapy,執行如下指令:
>conda install -c scrapinghub scrapy
安裝過程中,可能會有更新Conda的提示,根據提示選擇y就可以了,如圖3-4所示。
圖3-4 使用Conda安裝Scrapy
解決方法2
根據提示可知,錯誤是由安裝Twisted導緻的,是以需要先安裝Twisted。Twisted的下載下傳位址為
http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted,如圖3-5所示。根據Python和作業系統的版本,選擇對應的whl下載下傳檔案即可。其中,cp後面的數字是依賴的Python版本,amd64表示64位作業系統。下載下傳完後,定位到Twisted安裝包所在路徑,執行以下指令安裝Twisted。
>pip install Twisted-19.2.0-cp35-cp35m-win_amd64.whl
圖3-5 Twisted下載下傳頁
成功安裝Twisted後,就可以使用pip指令安裝Scrapy了。
3.3.3 驗證安裝
Scrapy安裝完成後,需要驗證安裝是否成功。在Python解釋器界面,輸入如下代碼:
>import scrapy
運作代碼後,如果沒有錯誤提示資訊,說明Scrapy已經安裝成功。
3.4 第一個網絡爬蟲
正确安裝Scrapy架構後,就可以建立Scrapy項目,實作第一個網絡爬蟲了。
3.4.1 需求分析
現要擷取起點中文網中小說熱銷榜的資料(網址為
https://www.qidian.com/rank/hotsales?style=1&page=1),如圖3-6所示。每部小說提取内容為:小說名稱、作者、類型和形式。
圖3-6 起點中文網中24小時熱銷榜
3.4.2 建立項目
首先,建立一個爬取起點中文網小說熱銷榜的Scrapy項目步驟如下:
(1)通過指令行定位到存放項目的目錄(如D盤的scrapyProject檔案夾)。
>d:
>cd d:scrapyProject
(2)建立一個名為qidian_hot的項目,指令如下:
>scrapy startproject qidian_hot
回車,得到如圖3-7所示的建立成功資訊。
圖3-7 生成Scrapy項目
(3)檢視項目結構。
在D盤的scrapyProject目錄下,自動生成了qidian_hot項目。使用PyCharm打開項目,如圖3-8所示為Scrapy項目的目錄結構,它對應于圖3-2中Scrapy的架構結構。
圖3-8 Scrapy項目架構
Scrapy中元件的本質是一個個Python源檔案,隻要在源檔案中實作各自的功能,爬蟲功能就能自動實作了。
3.4.3 分析頁面
通過Chrome浏覽器的“開發者工具”,分析頁面的HTML代碼,确定資料解析的XPath方法步驟如下:
(1)在Chrome浏覽器中,按F12鍵,顯示“開發者工具”欄。
(2)輸入網址
https://www.qidian.com/rank/hotsales?style=1&page=1,回車。
(3)此時将顯示24小時熱銷榜頁面。選擇“開發者工具”欄,單擊最左邊的元素選擇按鈕,将光标移動到任一部小說内容上并選中,對應的HTML代碼
就會被高亮顯示,具體操作如圖3-9所示。
(4)分析頁面結構。
不難發現,每部小說都包裹在元素中,逐層展開,就能定位到小說名稱、作者、類型和形式。
- 小說名稱:div(class=" book-mid-info ") → h4 → a → 文本。
- 作者:div(class=" book-mid-info ") → p(第1個)→ a(第1個)→ 文本。
- 類型:div(class=" book-mid-info ") → p(第1個)→ a(第2個)→ 文本。
-
形式:div(class=" book-mid-info ") → p(第1個)→ span → 文本。
使用XPath擷取小說内容,文法如下:
- 小說名稱:div[@class=" book-mid-info "]/ h4/a/text()。
- 作者:div[@class=" book-mid-info "]/ p[1]/a[1]/text()。
- 類型:div[@class=" book-mid-info "]/ p[1]/a[2]/text()。
- 形式:div[@class=" book-mid-info "]/ p[1]/span/text()。
帶你讀《從零開始學Scrapy網絡爬蟲》之三:Scrapy架構介紹第3章 Scrapy架構介紹
圖3-9 擷取小說内容對應的HTML代碼
3.4.4 實作Spider爬蟲功能
下面實作爬蟲功能。由圖3-8得知,爬蟲功能是在spiders目錄下實作的。實作的步驟如下:
(1)在spiders目錄下建立爬蟲源檔案qidian_hot_spider.py。
(2)在qidian_hot_spider.py檔案中定義HotSalesSpider類,實作爬蟲功能。
實作代碼如下:
#--coding:utf-8--
from scrapy import Request
from scrapy.spiders import Spider
class HotSalesSpider(Spider):
#定義爬蟲名稱
name = 'hot'
#起始的URL清單
start_urls = ["https://www.qidian.com/rank/hotsales?style=1"]
#解析函數
def parse(self, response):
#使用xpath定位到小說内容的div元素,儲存到清單中
list_selector = response.xpath("//div[@class='book-mid-info']")
#依次讀取每部小說的元素,從中擷取名稱、作者、類型和形式
for one_selector in list_selector:
#擷取小說名稱
name = one_selector.xpath("h4/a/text()").extract()[0]
#擷取作者
author = one_selector.xpath("p[1]/a[1]/text()").extract()[0]
#擷取類型
type = one_selector.xpath("p[1]/a[2]/text()").extract()[0]
#擷取形式(連載/完本)
form = one_selector.xpath("p[1]/span/text()").extract()[0]
#将爬取到的一部小說儲存到字典中
hot_dict = {"name":name, #小說名稱
"author":author, #作者
"type":type, #類型
"form":form} #形式
#使用yield傳回字典
yield hot_dict
以上代碼雖然添加了不少注釋,但相信大家了解起來還是有點困難。不用擔心,下一章将會詳細講解,這裡先成功運作一個爬蟲,建立信心和整體認識即可。
下面簡單說明HotSalesSpider的實作方法。
- 爬蟲所有的功能都是在類HotSalesSpider中實作的,它的基類為Spider。
- 類中定義了兩個屬性:name和start_urls。其中,name為爬蟲名稱,運作爬蟲時需要用到;start_urls中存儲的是目标網址的清單。如想要爬取兩頁熱銷榜的小說資訊,可以将start_urls修改為:
start_urls = ["https://www.qidian.com/rank/hotsales?style=1",
"https://www.qidian.com/rank/hotsales?style=1&page=3"]
類中定義了一個方法parse(),這是爬蟲的核心方法,通常完成兩個任務:
- 提取頁面中的資料。
- 提取頁面中的連結,并産生對連結頁面的下載下傳請求。
3.4.5 運作爬蟲
代碼完成後,就可以使用指令執行爬蟲了。
(1)通過指令行定位到qidian_hot項目目錄下(很重要)。
>cd D:scrapyProjectqidian_hot
(2)輸入爬蟲執行指令(hot為爬蟲名,hot.csv為儲存資料的檔案名)。
>scrapy crawl hot -o hot.csv
回車,爬蟲程式開始執行,指令提示符中會不斷顯示爬蟲執行時的資訊。爬蟲執行完後,資料會自動儲存于hot.csv檔案中。打開hot.csv檔案檢視資料,如圖3-10所示。
圖3-10 生成的CSV檔案
需要特别注意的是,爬蟲程式不能頻繁執行。因為網站一般都有反爬蟲措施,如頻繁執行會被認定是爬蟲程式,網站就會封掉你的IP,禁止通路。關于這個問題,下一章會給出解決方案。
3.4.6 常見問題
在生成的CSV檔案中,有時會發現資料之間會有空行間隔,如圖3-11所示。
圖3-11 有空行的CSV檔案
原因:這是Scrapy架構預設的組織形式,即資料之間以空行間隔。
解決方法:修改預設的組織形式。在Anaconda中找到exporters.py(筆者的是在C:Anaconda3Libsite-packagesscrapy目錄下)。打開源檔案,在類CsvItemExporter中添加一行代碼,如圖3-12所示。儲存檔案,重新運作爬蟲程式。
圖3-12 手動添加換行形式
3.5 本 章 小 結
本章首先介紹了網絡爬蟲的原理;接着介紹了Scrapy架構結構、執行流程及安裝過程;最後以爬取起點中文網小說24小時熱銷榜為例,實作了第一個Scrapy爬蟲案例,讓大家對Scrapy爬蟲有個初步的認識。