說明:文章是本人讀了崔慶才的Python3---網絡爬蟲開發實戰,作的簡單整理,但願能幫助正在學習的小夥伴~~
1. 準備工做:
安裝Scrapy框架、MongoDB和PyMongo庫,若是沒有安裝,google瞭解一下~~數據庫
2. 建立項目:
使用命令建立Scrapy項目,命令以下:json
scrapy startproject tutorial網絡
該命令能夠在任意文件夾運行,若是提示權限問題,能夠加sudo運行。該命令會建立一個名爲tutorial的文件夾,結構以下:數據結構
# scrapy.cfg: Scrapy項目的配置文件,定義了項目的配置文件路徑,部署相關信息等框架
# item.py: 定義item數據結構(爬取的數據結構)dom
# pipeline.py: 定義數據管道scrapy
# settings.py: 配置文件ide
# middlewares.py: 定義爬取時的中間件函數
# spiders: 放置Spiders的文件夾學習
3. 建立Spider:
Spider是本身定義的類,Scrapy用它來從網頁抓取內容,並解析抓取結果。該類必須繼承Scrapy提供的Spider類scrapy.Spider。
使用命令建立一個Spider,命令以下:
cd tutorial
scrapy genspider quotes quotes.toscrape.com
首先,進入剛纔建立的tutorial文件夾,而後執行genspider命令。第一個參數是spider的名稱,第二個參數是網絡域名(要抓取網絡的域名)。執行完畢後,spiders文件夾中多了一個quotes.py,它就是剛剛建立的Spider,內容以下:
該類中有三個屬性 ------ name、allowed_domains、start_urls,一個方法parse。
# name,惟一的名字,用來區分不一樣的Spider。
# allowed_domains,容許爬取的域名,若是初始或後續的請求連接不是該域名下的,則被過濾掉。
# start_urls,Spider在啓動時爬取的url列表,用來定義初始的請求。
# parse,它是spider的一個方法,用來處理start_urls裏面的請求返回的響應,該方法負責解析返回的響應,提取數據或進一步生成處理的請求。
4. 建立Item:
Item是保存爬取數據的容器,使用方法和字典相似。建立Item須要繼承scrapy.Item類,而且定義類型爲scrapy.Field的字段。
定義Item,將生成的items.py修改以下:
這裏定義了三個字段,接下來爬取時咱們會用到這個Item。
5. 解析Response:
前面咱們看到,parse()方法的參數response是start_urls裏面的連接爬取後的結果,因此在parse方法中,能夠對response變量包含的內容進行解析。網頁結構以下:
提取方式能夠是CSS選擇器或XPath選擇器。在這裏,使用CSS選擇器,parse()方法修改以下:
首先,利用選擇器選取全部的quote,並將其賦值給quotes變量,而後利用for循環對每個quote遍歷,解析每個quote的內容。
對text來講,他的class是text,因此用.text選擇器來選取,這個結果其實是整個帶有標籤的節點,要獲取它的正文內容,能夠加::text來獲取。這時的結果是長度爲1的列表,因此還須要用extract_first()方法來獲取第一個元素。
而對於tags來講,因爲咱們要獲取全部的標籤,因此用extract()方法來獲取整個列表便可。
6. 使用Item:
上面定義了Item,這邊咱們就須要用到它。Item能夠理解爲一個字典,不過在這裏須要先實例化,而後將解析的結果賦值給Item的每個字段,最後返回Item。
修改QuotesSpider類以下:
至此,首頁的全部內容被解析出來了,並將結果賦值給一個個TutorialItem。
7. 後續Request:
上面實現了網頁首頁的抓取解析,那麼下一頁怎麼抓取呢?咱們能夠看到網頁的翻頁結構以下:
這裏有一個Next按鈕,查看源碼,能夠看出下一頁的全連接是:http://quotes.toscrape.com/page/2/,經過這個連接咱們就能夠構造下一個請求。
構造請求須要用到scrapy.Request。這裏會有兩個參數 -------url和callback。
# url,請求連接。
# callback,回調函數。請求完畢後,獲取響應,引擎會將該響應做爲參數傳遞給回調函數,回調函數進行解析或生成下一個請求。
在parse()方法中追加以下代碼:
第一句,獲取下一個頁面的連接,即要獲取a超連接中的href屬性。
第二句,調用urljoin()方法,urljoin()方法能夠將相對URL構形成一個絕對URL。例如,獲取獲得下一頁的地址是/page/2/,urljoin()方法處理後的結果是:http://quotes.toscrape.com/page/2/。
第三句,經過url和callback變量構造了一個新的請求,回調函數callback依然使用parse()方法。這樣,爬蟲就進入了一個循環,直到最後一頁。
修改以後,整個Spider類以下:
8. 運行:
進入目錄,運行以下命令:
scrapy crawl quotes
就能夠看到Scrapy的運行結果了。
9. 保存到文件:
運行完Scrapy後,咱們只在控制檯看到了輸出結果。如何保存結果呢?
Scrapy提供了Feed Exports能夠輕鬆將結果輸出。例如,咱們想將上面的結果保存成JSON文件,能夠執行以下命令:
scrapy crawl quotes -o quotes.json
命令運行後,會發現項目內多了一個quotes.json文件,這個文件包含了抓取的全部內容,格式爲JSON。
另外,還支持其餘格式以下:
scrapy crawl quotes -o quotes.jsonlines (scrapy crawl quotes -o quotes.jl , jl是jsonlines的縮寫)
scrapy crawl quotes -o quotes.csv
scrapy crawl quotes -o quotes.xml
scrapy crawl quotes -o quotes.pickle
scrapy crawl quotes -o quotes.marshal
scrapy crawl quotes -o ftp://user:pass@ftp.example.com/path/to/quotes.csv (遠程輸出,須要正確配置,不然會報錯)
10. 使用Pipeline:
若是想進行復雜額操做,如將結果保存到MongoDB數據庫,或者篩選Item,咱們能夠定義Pipeline來實現。
前面提到,Pipeline是項目管道,當Item生成後,它會自動被送到Pipeline進行處理,主要的操做以下:
# 清理HTML數據
# 驗證爬取的數據,檢查爬取的字段
# 查重並丟棄重複內容
# 將結果保存到數據庫
實現Pipeline,只須要定義一個類並實現process_item()方法便可。啓用Pipeline後,Pipline會自動調用這個方法。process_item()方法必須返回包含數據的字典或item對象,或者拋出DropItem異常。
process_item()方法有兩個參數,一個參數是item,每次Spider生成的Item都會做爲參數傳遞過來,另外一個參數是spider,就是Spider的實例。
接下來,咱們實現一個Pipline,篩掉text長度大於50的Item,並將結果保存到MongoDB數據庫。
修改pipelines.py以下:
# from_crawler,這是一個類方法,用@classmethod標識,是一種依賴注入。它的參數就是crawler,經過crawler能夠拿到全局配置的每個配置信息。在全局配置settings.py中,能夠配置MONGO_UR和MONGO_DB來指定MongoDB鏈接須要的地址和數據庫名稱,拿到配置信息以後返回類對象便可。因此這個方法主要是用來獲取settings.py中的配置信息。
# open_spider,當Spider開啓時,這個方法被調用。進行初始化操做。
# close_spider,當Spider關閉時,這個方法被調用。將數據庫鏈接關閉。
最主要的process_item()方法則進行了數據插入操做。
定義好的TutorialPipeline和MongoPipline這兩個類後,咱們須要在settings.py中使用它們,MongoDB的鏈接信息也須要在settings.py中定義。
settings.py中加入以下內容:
賦值ITEM_PIPELINES字典,鍵名是Pipeline的類名稱,鍵值是調用的優先級,是一個數字,數字越小對應的Pipeline越先被調用。
從新執行以下命令進行爬取:
scrapy crawl quotes
結束後,MongoDB中會建立了一個tutorial的數據庫、TutorialItem的表,以下圖:
11. 結語:
至此,一個簡單的Scrapy框架爬蟲就完成了,這只是一個簡單的爬蟲例子,想要了解更多,能夠去看看崔慶才的書---------《Python3 網絡爬蟲開發實戰》。
Github上面也有許多相關的項目能夠去研究~~~