scrapy入門到放棄02:整一張架構圖,開發一個程式

前言

Scrapy開門篇寫了一些純理論知識,這第二篇就要直奔主題了。先來講講Scrapy的架構,並從零開始開發一個Scrapy爬蟲程式。

本篇文章主要闡述Scrapy架構,理清開發流程,掌握基本操作。

整體架構

自己動手畫架構圖一張:

Scrapy架構

這就是Scrapy的整體架構,看起來流程比較複雜,但其實需要開發者參與的部分不多。這裡先介紹一下各個部分。

  1. Spider:要開發的爬蟲程式,用來定義網站入口,實現解析邏輯並發起請求。
  2. Pipeline:數據管道,可自定義實現數據持久化方式。
  3. Middleware:中間件,分為兩類。一類是下載器中間件,主要處理請求,用於添加請求頭、代理等;一類是spider中間件,用於處理響應,用的很少。
  4. Scheduler:調度器,用來存放爬蟲程式的請求。
  5. Downloader:下載器。對目標網站發起請求,獲取響應內容。

一個完整的爬蟲,開發者需要參與1、2、3部分的開發。甚至最簡單的爬蟲,只需要開發Spider部分即可。

準備工作

安裝Scrapy

Scrapy的安裝和普通模組相同:

pip3 install scrapy

安裝之後,就會多出一個scrapy命令,我們可以使用此命令來新建項目、新建爬蟲程式、進入shell交互環境等等。

命令說明如下圖:

scrapy

新建項目

和普通python項目不同的是,Scrapy需要使用命令行新建項目,然後再導入IDE進行開發。

scrapy startproject [ProjectName]

執行上面命令,新建一個新的Scrapy項目。

startproject

從項目結構可以看出,一個Scrapy項目分為四大模組,與架構中各個部分對應。

四大模組

新建爬蟲程式

將項目導入IDE,spiders包用於存放開發的爬蟲程式。而爬蟲程式的新建也是通過命令行操作。

# domain就是域名,例如百度域名就是www.baidu.com
scrapy genspider [SpiderName] [domin]

在本scrapy項目任何目錄下的命令行中執行此命令,都會在spiders下新建一個爬蟲程式。

genspider

爬蟲程式開發

如圖,scrapy爬蟲程式已經生成,在其中實現解析規則程式碼即可完成開發。

這裡依然以斗羅大陸為例,程式程式碼如下。

斗羅大陸

程式結構

每個Scrapy程式都會有三個模組:

  1. name:每個項目中的爬蟲的名稱,作為唯一標識用於爬蟲的啟動
  2. allowed_domains:主要用於限定運行爬蟲網站的域名
  3. start_urls::網站入口,起始url
  4. 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使用的參數如下順序排列:

  1. url:要請求的url
  2. callback:處理響應的回調函數
  3. meta:字典,通過響應傳遞kv數據給回調函數
  4. dont_filter:默認為False,即開啟url去重。如果我們在start_urls寫入兩條一樣的url時,只會輸出一次結果,如果我們修改為True,則輸出兩次。
  5. method:請求方式,默認為get
  6. 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功能。

Debug

scrapy shell交互環境

我們可以shell交互環境中進行解析程式碼的調試。

scrapy shell //v.qq.com/detail/m/m441e3rjq9kwpsc.html

輸入命令回車,對斗羅大陸頁面發起請求並進入shell環境。

shell

如圖所示,在進入shell環境後,自動封裝了一些變數,這裡我們只關注響應response。

response

如圖,我們在shell交互環境中對網頁進行了解析。這樣,我們將測試好的解析程式碼複製到程式中即可,這樣提高了開發效率。

輸入view(response),敲擊回車,將自動在瀏覽器打開頁面。

結語

在樣常式序中,請求和響應只在架構圖右半邊簡單地流轉,如果想要持久化,還需要定義pipeline等等,而且程式中也只寫了一層解析函數,即parse()。

如果在parse中還要進行深度爬取,我們也要在parse中發起請求,並定義新的callback回調函數來進行解析,一直到我們想要的數據頁面為止。當然,這些後面都會講到。

自Scrapy系列寫了開篇之後,就擱置了很久。一是最近的確挺忙的,二是Scrapy知識點比較多,一時間不知該從何處寫起。不過我還是會繼續寫下去的,雖然可能更新的有點慢,歡迎小夥伴催更、也希望多多提出寶貴的意見。


95後小程式設計師,寫的都是日常工作中的親身實踐,置身於初學者的角度從0寫到1,詳細且認真。


文章會在公眾號 [入門到放棄之路] 首發,期待你的關注。

感謝每一份關注