Python爬蟲5.2 — scrapy框架pipeline模塊的使用

綜述

本系列文檔用於對Python爬蟲技術的學習進行簡單的教程講解,鞏固自己技術知識的同時,萬一一不小心又正好對你有用那就更好了。
Python 版本是3.7.4

上一篇文章我們簡單入門了Scrapy框架,並且使用Scrapy框架實現了一個爬蟲項目。這一篇我們就詳細的介紹一下Scrapy框架中的pipeline使用方法(雖然上篇文章我們也稍微詳細的講了pipeline存儲數據的優化方式,這篇我們主要講解如果一個項目多個爬蟲,如何使用一個pipeline進行接收數據的問題)。

pipeline核心方法

我們可以自定義Pipeline,只需要實現指定的方法,其中必須要實現的一個方法是:process_item(item, spider)

另外還有如下幾個比較實用的方法:

  • open_spider(spider)
  • close_spider(spider)
  • close_spider()方法是在Spider關閉的時候自動調用的。在這裏我們可以做一些收尾工作,如關閉數據庫連接等。其中,參數spider就是被關閉的Spider對象。
  • from_crawler(cls, crawler)

process_item(item, spider)

process_item()是必須要實現的方法,被定義的ItemPipeline會默認調用這個方法對Item進行處理。比如,我們可以進行數據處理或者將數據寫入到數據庫等操作。它必須返回Item類型的值或者拋出一個DropItem異常

close_spider(spider)

open_spider()方法是在Spider開啓的時候被自動調用的。在這裏我們可以做一些初始化操作,如開啓數據庫連接等。其中,參數spider就是被開啓的Spider對象。

close_spider(spider)

close_spider()方法是在Spider關閉的時候自動調用的。在這裏我們可以做一些收尾工作,如關閉數據庫連接等。其中,參數spider就是被關閉的Spider對象。

from_crawler(cls, crawler)

from_crawler()方法是一個類方法,用@classmethod標識,是一種依賴注入的方式。它的參數是crawler,通過crawler對象,我們可以拿到Scrapy的所有核心組件,如全局配置的每個信息,然後創建一個Pipeline實例。參數cls就是Class,最後返回一個Class實例。

使用pipeline

從pipeline的字典形式可以看出來,pipeline可以有多個,而且確實pipeline能夠定義多個。

爲什麼需要多個pipeline:

  1. 一個spider的內容可能要做不同的操作,比如存入不同的數據庫中
  2. 可能會有多個spider,不同的pipeline處理不同的item的內容

注意:

  1. 使用pipeline需要在setting.py中進行配置
  2. pipeline的權重值越小優先級越高
  3. pipeline中process_item不能修改爲其他名稱

一個spider多個item類型結構情況

我們使用命令創建一個spider程序:

scrapy genspider qsbk_spider qiushibaike.com

將需要配置的信息配置好,這裏不再說明。然後在qsbk_spider.py中寫入如下代碼:

import scrapy


class QsbkSpiderSpider(scrapy.Spider):
    name = 'qsbk_spider'
    allowed_domains = ['qiushibaike.com']
    start_urls = ['http://qiushibaike.com/']

    def parse(self, response):
        item = {}
        # 我們進行奇數偶數的不同參數處理
        for i in range(0, 50):
            if (i % 2) == 0:
                # 偶數處理
                item['come_from'] = 'oushu'
                item['data'] = i
            else:
                # 奇數處理
                item['come_from'] = 'jishu'
                item['data'] = i
            yield item

然後再pipelines.py中寫入如下代碼:

class MyspiderPipeline(object):
    def process_item(self, item, spider):

        # 增加if判斷傳來的item是什麼數據,然後進行相對應的邏輯判斷
        if item['come_from'] == 'jishu':
            # code..
            print('%d 是奇數' % item['data'])
        else:
            # code ..
            print('%d 是偶數' % item['data'])

        return item

運行成功即可查看效果。或者在pipeline定義多個類,代碼如下:

class MyspiderPipeline(object):
    def process_item(self, item, spider):

        # 增加if判斷傳來的item是什麼數據,然後進行相對應的邏輯判斷
        if item['come_from'] == 'jishu':
            # code..
            print('%d 是奇數' % item['data'])

        return item


class MyspiderPipeline1(object):
    def process_item(self, item, spider):
        # 增加if判斷傳來的item是什麼數據,然後進行相對應的邏輯判斷
        if item['come_from'] == 'oushu':
            # code..
            print('%d 是偶數' % item['data'])

        return item

然後再配置文件中配置:

ITEM_PIPELINES = {
    'mySpider.pipelines.MyspiderPipeline': 300,
    'mySpider.pipelines.MyspiderPipeline1': 301,
}

運行可以查看到同樣的效果。

多個spider情況

多個spider我們也可以使用上面的那種方式進行處理,再item中增加數據標識,然後根據標識進行不同的處理。除上述外,我們還可以使用另一種方式判斷。具體使用方法如下:

我分別使用三個命令創建了三個spider程序:

# 爬取糗百的“文字”模塊
scrapy genspider qsbk1_spider qiushibaike.com
# 爬取糗百的“糗圖”模塊
scrapy genspider qsbk2_spider qiushibaike.com
# 爬取糗百的“穿越模塊”
scrapy genspider qsbk3_spider qiushibaike.com

分別運行完三條創建爬蟲命令之後,你會在spider文件夾下發現新增了qsbk1_spider.pyqsbk2_spider.pyqsbk3_spider.py三個文件,這就是我們新建的三個爬蟲模塊文件(項目目錄結構就不在這裏貼了)。可以通過命令scrapy list查看項目中創建的爬蟲列表。

在三個文件中分別寫入如下代碼:

  1. qsbk1_spider.py
    import scrapy
    
    
    class Qsbk1SpiderSpider(scrapy.Spider):
        name = 'qsbk1_spider'
        allowed_domains = ['qiushibaike.com']
        start_urls = ['https://www.qiushibaike.com/text/']
    
        def parse(self, response):
            item = {}
            # 這是qsbk1_spider返回的數據
            for i in range(0, 10):
                item['come_from'] = 'qsbk1'
                item['data'] = i
                yield item
    
  2. qsbk2_spider.py
    import scrapy
    
    
    class Qsbk2SpiderSpider(scrapy.Spider):
        name = 'qsbk2_spider'
        allowed_domains = ['qiushibaike.com']
        start_urls = ['https://www.qiushibaike.com/pic/']
    
        def parse(self, response):
            item = {}
            # 這是qsbk2_spider返回的數據
            for i in range(10, 20):
                item['come_from'] = 'qsbk2'
                item['data'] = i
                yield item
    
  3. qsbk3_spider.py
    import scrapy
    
    
    class Qsbk3SpiderSpider(scrapy.Spider):
        name = 'qsbk3_spider'
        allowed_domains = ['qiushibaike.com']
        start_urls = ['https://www.qiushibaike.com/history/']
    
        def parse(self, response):
            item = {}
            # 這是qsbk3_spider返回的數據
            for i in range(20, 30):
                item['come_from'] = 'qsbk3'
                item['data'] = i
                yield item
    

最後三個爬蟲爬取的數據都放到了pipeline中,這就需要我們在pipeline中進行判斷是那個爬蟲傳過來的數據。pipelines.py代碼如下:

class MyspiderPipeline(object):
    def process_item(self, item, spider):

        # 這是我們可以根據spider來進行判斷
        if spider.name == 'qsbk1_spider':
            print("這是qsbk1的數據:", item)
        elif spider.name == 'qsbk2_spider':
            print("這是qsbk2的數據:", item)
        elif spider.name == 'qsbk3_spider':
            print("這是qsbk3的數據:", item)
        else:
            print('未知數據')
        return item

運行爬蟲即可看到相應的打印效果。

使用多個items進行區分

編寫items.py代碼如下:

import scrapy


class Qsbk1Item(scrapy.Item):
    """
    qsbk1爬蟲items類
    """
    num = scrapy.Field()


class Qsbk2Item(scrapy.Item):
    """
    qsbk2爬蟲items類
    """
    num = scrapy.Field()


class Qsbk3Item(scrapy.Item):
    """
    qsbk3爬蟲items類
    """
    num = scrapy.Field()

編寫qsbk1_spider.py代碼如下(其他兩個爬蟲類似):

import scrapy
# 引入對應的items類
from mySpider.items import Qsbk1Item


class Qsbk1SpiderSpider(scrapy.Spider):
    name = 'qsbk1_spider'
    allowed_domains = ['qiushibaike.com']
    start_urls = ['https://www.qiushibaike.com/text/']

    def parse(self, response):
        for i in range(0, 10):
            item = Qsbk1Item(num=i)
            yield item

編寫pipeline.py代碼如下:

# 引入對應的items類
from mySpider.items import Qsbk1Item
from mySpider.items import Qsbk2Item
from mySpider.items import Qsbk3Item


class MyspiderPipeline(object):
    def process_item(self, item, spider):

        # 這是我們可以根據items類來進行判斷
        if isinstance(item, Qsbk1Item):
            print("這是qsbk1的數據:", item)
        elif isinstance(item, Qsbk2Item):
            print("這是qsbk2的數據:", item)
        elif isinstance(item, Qsbk3Item):
            print("這是qsbk3的數據:", item)
        else:
            print('未知數據')
        return item

運行爬蟲即可看到效果

其他博文鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章