scrapy入門到放棄02:整一張架構圖,開發一個程式
前言
Scrapy開門篇寫了一些純理論知識,這第二篇就要直奔主題了。先來講講Scrapy的架構,並從零開始開發一個Scrapy爬蟲程式。
本篇文章主要闡述Scrapy架構,理清開發流程,掌握基本操作。
整體架構
自己動手畫架構圖一張:
這就是Scrapy的整體架構,看起來流程比較複雜,但其實需要開發者參與的部分不多。這裡先介紹一下各個部分。
- Spider:要開發的爬蟲程式,用來定義網站入口,實現解析邏輯併發起請求。
- Pipeline:資料管道,可自定義實現資料持久化方式。
- Middleware:中介軟體,分為兩類。一類是下載器中介軟體,主要處理請求,用於新增請求頭、代理等;一類是spider中介軟體,用於處理響應,用的很少。
- Scheduler:排程器,用來存放爬蟲程式的請求。
- Downloader:下載器。對目標網站發起請求,獲取響應內容。
一個完整的爬蟲,開發者需要參與1、2、3部分的開發。甚至最簡單的爬蟲,只需要開發Spider部分即可。
準備工作
安裝Scrapy
Scrapy的安裝和普通模組相同:
pip3 install scrapy
安裝之後,就會多出一個scrapy命令,我們可以使用此命令來新建專案、新建爬蟲程式、進入shell互動環境等等。
命令說明如下圖:
新建專案
和普通python專案不同的是,Scrapy需要使用命令列新建專案,然後再匯入IDE進行開發。
scrapy startproject [ProjectName]
執行上面命令,新建一個新的Scrapy專案。
從專案結構可以看出,一個Scrapy專案分為四大模組,與架構中各個部分對應。
新建爬蟲程式
將專案匯入IDE,spiders包用於存放開發的爬蟲程式。而爬蟲程式的新建也是通過命令列操作。
# domain就是域名,例如百度域名就是www.baidu.com
scrapy genspider [SpiderName] [domin]
在本scrapy專案任何目錄下的命令列中執行此命令,都會在spiders下新建一個爬蟲程式。
爬蟲程式開發
如圖,scrapy爬蟲程式已經生成,在其中實現解析規則程式碼即可完成開發。
這裡依然以斗羅大陸為例,程式程式碼如下。
程式結構
每個Scrapy程式都會有三個模組:
- name:每個專案中的爬蟲的名稱,作為唯一標識用於爬蟲的啟動
- allowed_domains:主要用於限定執行爬蟲網站的域名
- start_urls::網站入口,起始url
- parse:預設的第一個解析函式
上面說道,start_urls是爬蟲程式的入口,那麼它是怎麼發起請求,並將Res響應傳給parse解析?作為一個list型別,是否可以有多個入口url?
start_requests()
每個爬蟲程式都繼承了Spider類,裡面的start_requests方法用來發起請求,並自動將響應傳遞給parse()。
如圖,我們可以看到,此方法遍歷了start_urls來發起了請求。那麼,我就不想傳遞給parse()解析,我就想自定義方法,啷個怎麼辦來?
小事莫慌,我們重寫start_requests就好了嘛。
如圖,我們自定義了parse_first解析函式,在發起請求時使用callback來指定回撥函式,這裡記住:函式名一定不要加括號,加括號表示立即執行此函式,不加代表是引用。
修改後的程式輸出結果和之前相同。
Request
我們使用yield Request發起一個請求,為什麼不用return?因為yield不會立即返回,不會終結方法。這裡就涉及到了生成器的問題,有興趣的可以去研究一下。
Request使用的引數如下順序排列:
- url:要請求的url
- callback:處理響應的回撥函式
- meta:字典,通過響應傳遞kv資料給回撥函式
- dont_filter:預設為False,即開啟url去重。如果我們在start_urls寫入兩條一樣的url時,只會輸出一次結果,如果我們修改為True,則輸出兩次。
- method:請求方式,預設為get
- priority:請求優先順序,預設為0,數值越大優先順序越大
至於cookies、headers引數,我們可以在Request設定,但大多時候都是在下載器middleware中進行設定。
爬蟲程式啟動
Scrapy爬蟲程式的啟動主要有兩種方式。
命令列啟動
第一種就是在scrapy專案目錄下的命令列下啟動。
scrapy crawl [SpiderName]
這種啟動方式的缺點顯而易見,就是無法IDE中使用Debug功能,所以這種方式通常用於生產。
IDE啟動
我們在開發過程中通常使用第二種啟動方式,這也是符合我們常規啟動程式的方式。新建一個python程式,引入命令列工具執行爬蟲啟動命令。
from scrapy.cmdline import execute
if __name__ == "__main__":
execute("scrapy crawl DouLuoDaLu".split(" "))
這樣就可以在IDE中啟動程式,並使用Debug功能。
scrapy shell互動環境
我們可以shell互動環境中進行解析程式碼的除錯。
scrapy shell https://v.qq.com/detail/m/m441e3rjq9kwpsc.html
輸入命令回車,對斗羅大陸頁面發起請求並進入shell環境。
如圖所示,在進入shell環境後,自動封裝了一些變數,這裡我們只關注響應response。
如圖,我們在shell互動環境中對網頁進行了解析。這樣,我們將測試好的解析程式碼複製到程式中即可,這樣提高了開發效率。
輸入view(response),敲擊回車,將自動在瀏覽器開啟頁面。
結語
在樣例程式中,請求和響應只在架構圖右半邊簡單地流轉,如果想要持久化,還需要定義pipeline等等,而且程式中也只寫了一層解析函式,即parse()。
如果在parse中還要進行深度爬取,我們也要在parse中發起請求,並定義新的callback回撥函式來進行解析,一直到我們想要的資料頁面為止。當然,這些後面都會講到。
自Scrapy系列寫了開篇之後,就擱置了很久。一是最近的確挺忙的,二是Scrapy知識點比較多,一時間不知該從何處寫起。不過我還是會繼續寫下去的,雖然可能更新的有點慢,歡迎小夥伴催更、也希望多多提出寶貴的意見。
95後小程式設計師,寫的都是日常工作中的親身實踐,置身於初學者的角度從0寫到1,詳細且認真。
文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。