介紹
Scrapy是一個快速且高效的網頁抓取架構,用于抓取網站并從中提取結構化資料。它可用于多種用途,從資料挖掘到監控和自動化測試。
相比于自己通過requests等子產品開發爬蟲,scrapy能極大的提高開發效率,包括且不限于以下原因:
- 它是一個異步架構,并且能通過配置調節并發量,還可以針對域名或ip進行精準控制
- 内置了xpath等提取器,友善提取結構化資料
- 有爬蟲中間件和下載下傳中間件,可以輕松地添加、修改或删除請求和響應的處理邏輯,進而增強了架構的可擴充性
- 通過管道方式存儲資料,更加友善快捷的開發各種資料儲存方式
安裝
conda:
conda install -c conda-forge scrapy
pip:
pip install Scrapy
架構
各個子產品的功能介紹
1.引擎(Engine) :
- 負責控制整個爬取流程的核心子產品。
- 将請求配置設定給下載下傳器,并處理從下載下傳器傳回的響應。
- 負責排程器和下載下傳器之間的協調工作,確定請求的順利處理和資料的流通。
2.排程器(Scheduler) :
- 接受引擎發來的請求,并根據一定的政策(如FIFO、LIFO等)将這些請求放入隊列中,以便後續的處理。
- 防止重複請求的生成,確定爬取過程的有效性。
3.下載下傳器(Downloader) :
- 負責下載下傳網頁資料,發送HTTP請求并接收響應。
- 可配置代理、使用者代理、cookies等資訊,以模拟浏覽器行為。
- 處理HTTP響應,将結果傳遞給引擎。
4.中間件(Middleware) :
- 攔截和處理引擎、排程器、下載下傳器之間的請求和響應。
- 可以在請求發出前進行預處理,或在響應傳回後進行後處理。
- 可以進行使用者自定義的操作,例如添加代理、修改請求頭等。
5.爬蟲(Spider) :
- 使用者編寫的用于定義如何爬取特定網站的類。
- 包括起始URL、如何跟蹤連結、如何提取資料等。
- 定義如何解析下載下傳的頁面并提取所需資料的規則。
6.項目管道(Item Pipeline) :
- 處理爬取到的資料,包括清洗、驗證、存儲等操作。
- 通過多個項目管道進行資料處理,可以靈活應對不同類型資料的處理需求。
7.排程器中間件(Scheduler Middleware) :
- 用于對請求的排程過程進行自定義的攔截和處理。
- 可以在請求入隊列前或出隊列後進行一些處理,例如動态修改優先級、過濾請求等。
8.擴充(Extensions) :
- 用于監聽Scrapy的信号、修改配置、添加新指令等。
- 可以用于監控爬取過程、記錄日志、實作定制化需求等。
以上是對Scrapy架構中各個子產品的詳細介紹,每個子產品都有其獨特的功能和作用,通過它們的協作,Scrapy能夠完成從網頁爬取到資料處理的整個流程,在接下來的文章中,也會有各個子產品的開發教程
運作流程
1.配置爬蟲(Spider)并啟動引擎(Engine) :
- 使用者編寫具體的爬蟲類,定義了如何爬取特定網站的規則。
- 使用者通過指令行或代碼方式啟動Scrapy引擎,指定要運作的爬蟲。
2.引擎排程請求到排程器(Scheduler) :
- 引擎将起始請求發送給排程器,排程器根據一定的政策将請求放入隊列中,等待下載下傳器處理。
- 排程器會控制請求的優先級、去重邏輯等。
3.下載下傳器(Downloader)擷取并處理請求:
- 下載下傳器從排程器擷取請求,然後發送HTTP請求到目标網站。
- 下載下傳器接收目标網站的HTTP響應,将響應傳遞給引擎。
4.引擎将響應發送給Spider處理:
- 引擎接收到下載下傳器傳回的響應,然後将響應發送給對應的Spider進行處理。
- Spider根據預定義的規則解析響應,提取所需的資料,并生成新的請求或資料項。
5.處理資料項(Item) :
- 爬蟲将從頁面中提取的資料封裝成資料項(Item),并将其發送給項目管道(Item Pipeline)進行處理。
- 項目管道可以負責資料的清洗、驗證、存儲等操作,使用者可以自定義多個項目管道,以便處理不同類型的資料。
6.資料持久化:
- 經過項目管道處理後的資料項可以被持久化存儲到資料庫、檔案等目的地。
7.循環執行直到完成:
- 整個爬取流程會循環執行,直到隊列中沒有新的請求,或者爬取任務被手動終止。
8.擴充和監控:
- 使用者可以通過擴充(Extensions)來監聽Scrapy的信号、修改配置、添加新指令等,以實作定制化需求。
- 可以使用日志和其他監控工具來監控爬取過程,確定爬蟲正常運作。
總的來說,Scrapy運作模式是基于異步事件驅動的,各個子產品之間通過事件和回調函數進行互動,整個爬取過程由引擎統一協調控制。這種模式使得Scrapy能夠高效地處理大規模的爬取任務,并且具有良好的可擴充性和靈活性。
使用
使用下述指令建立第一個scrapy項目:scrapy startproject JuejinProject
其中JuejinProject是項目名,會得到如下結構:
各檔案作用如下:
- scrapy.cfg:項目的配置檔案,可以把架構相關配置寫入。
- JuejinProject/items.py:定義結構化的資料模型。
- JuejinProject/pipelines.py:用來持久化存儲資料模型。
- JuejinProject/settings.py:項目的設定檔案。
- JuejinProject/spiders/:爬蟲存放目錄。
使用下述指令建立爬蟲:
scrapy genspider toscrape quotes.toscrape.com/page/1/格式為"scrapy genspider 爬蟲名 起始url" 這時你會發現在spiders路徑下多了一個toscrape.py檔案,添加注釋後内容如下:
import scrapy
class ToscrapeSpider(scrapy.Spider):
# 爬蟲名
name = "toscrape"
# 允許的域名
allowed_domains = ["quotes.toscrape.com"]
# 起始url,第一個請求
start_urls = ["https://quotes.toscrape.com/page/1/"]
def parse(self, response):
"""
預設的解析方法,請求得到的response對象會傳入此方法
:param response:
:return:
"""
pass
想使用xpath解析出指定字段需要使用xpath相關方法:
import scrapy
class ToscrapeSpider(scrapy.Spider):
# 爬蟲名
name = "toscrape"
# 允許的域名
allowed_domains = ["quotes.toscrape.com"]
# 起始url,第一個請求
start_urls = ["https://quotes.toscrape.com/page/1/"]
def parse(self, response):
"""
預設的解析方法,請求得到的response對象會傳入此方法
:param response:
:return:
"""
quotes = response.xpath('//div[@class="quote"]')
for quote in quotes:
quote_text = quote.xpath('.//span[@class="text"]/text()').extract_first()
print(quote_text)
if __name__ == '__main__':
# 使用此方法可以對爬蟲進行debug
from scrapy.cmdline import execute
execute('scrapy crawl toscrape'.split())
運作這段代碼就可以得到頁面上的人物發言了:
這隻是最簡單的一個例子,将資料輸出到了控制台,在生産中,會有更複雜的問題需要解決,比如遇到反爬怎麼處理?怎麼把資料存入資料庫?代碼異常如何及時發現?網站有反爬怎麼處理?在下邊的章節,我将逐個解決遇到的問題,讓scrapy更好的為你所用。
作者:煉數成金
連結:https://juejin.cn/post/7373507761127505971