天天看點

Python高效爬蟲——scrapy介紹與使用

作者:網際網路進階架構師

介紹

Scrapy是一個快速且高效的網頁抓取架構,用于抓取網站并從中提取結構化資料。它可用于多種用途,從資料挖掘到監控和自動化測試。

相比于自己通過requests等子產品開發爬蟲,scrapy能極大的提高開發效率,包括且不限于以下原因:

  1. 它是一個異步架構,并且能通過配置調節并發量,還可以針對域名或ip進行精準控制
  2. 内置了xpath等提取器,友善提取結構化資料
  3. 有爬蟲中間件和下載下傳中間件,可以輕松地添加、修改或删除請求和響應的處理邏輯,進而增強了架構的可擴充性
  4. 通過管道方式存儲資料,更加友善快捷的開發各種資料儲存方式

安裝

conda:

conda install -c conda-forge scrapy           

pip:

pip install Scrapy           

架構

Python高效爬蟲——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是項目名,會得到如下結構:

Python高效爬蟲——scrapy介紹與使用

各檔案作用如下:

  • 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())           

運作這段代碼就可以得到頁面上的人物發言了:

Python高效爬蟲——scrapy介紹與使用

這隻是最簡單的一個例子,将資料輸出到了控制台,在生産中,會有更複雜的問題需要解決,比如遇到反爬怎麼處理?怎麼把資料存入資料庫?代碼異常如何及時發現?網站有反爬怎麼處理?在下邊的章節,我将逐個解決遇到的問題,讓scrapy更好的為你所用。

作者:煉數成金

連結:https://juejin.cn/post/7373507761127505971