爬虫工作量由小到大的思维转变---<第三十八章 Scrapy redis里面的item问题 >

发布时间:2024年01月22日

前言:

Item是Scrapy中用于保存爬取到的数据的容器,而Scrapy-Redis在存储Item时带来了一些变化和灵活性。因此,需要把它单独摘出来讲一讲,很重要!

正文:

存储形式

Scrapy-Redis中的Item存储方式可以有多种形式,以下是几种常见的形式及其适用情况:

  1. 存储为字典形式: 在Scrapy-Redis中,Item可以被转换为字典形式,并以JSON字符串的形式存储到Redis中。这种形式适用于存储结构简单的数据,例如只包含几个字段的Item。字典形式的Item便于存储和解析,并且可以提供较好的可读性
  2. 存储为二进制数据(BLOB): Scrapy-Redis还允许将Item以二进制数据的形式存储到Redis中,而不是转换为字典形式。这种形式适用于需要保存复杂结构的Item,包括嵌套的数据结构或二进制数据。将Item存储为二进制数据可以更好地保留其原有的数据结构和格式,但在读取和处理时需要进行适当的解析和转换。
  3. 存储为Hash结构: Redis中的Hash结构可以用于存储Item数据,其中Item的字段名作为Hash的键,字段值作为Hash的值。这种形式适用于存储字段较多或结构复杂的Item数据。Hash结构的存储方式提供了一种有效的方式来组织和查询Item数据,可以方便地根据字段名进行查找和更新操作

区别与正常的Scrapy中的Item:


与正常的Scrapy中的Item相比,Scrapy-Redis存储Item的操作范围发生了变化,并引入了更多的灵活性和可扩展性。

  1. 存储位置: 在正常的Scrapy中,Item通常是通过Pipeline存储到本地文件或数据库中。而在Scrapy-Redis中,Item一般存储到Redis中,以便在分布式环境中实现多个Scrapy进程之间的数据共享和协同工作。
  2. 存储格式: 在正常的Scrapy中,Item通常是以字典的形式进行存储和传递。而在Scrapy-Redis中,Item可以以多种形式进行存储,包括字典形式、二进制数据形式或Hash结构形式,具体选择取决于数据结构的复杂性和存储需求。
  3. 存储方式的灵活性: Scrapy-Redis提供了多种存储Item的方式,可以根据具体需求选择最适合的方式。通过灵活的存储方式,可以更好地适应不同类型和结构的数据,提供更大的存储和处理灵活性。

当一个Scrapy-Redis爬虫有多个Item时,可以采取以下几种解决方案:

  1. 使用单一的Redis Key:将多个Item存储到相同的Redis Key 下。在Pipeline中判断不同的Item类型,根据Item类型的不同,将数据转换成对应的格式存储到Redis中。这种方法适用于Item之间的数据没有强关联性,且数量较少的情况。

  2. 使用不同的Redis Key:为每个Item类型分别指定不同的Redis Key,将不同类型的Item存储到不同的Key下。在Pipeline中根据Item类型,选择对应的Redis Key 进行存储。这种方法适用于Item之间有明显的区分和逻辑关系,并且数量较多的情况。

  3. 使用Hash结构存储:将多个Item作为Hash结构的字段存储到Redis中。每个Item类型对应Hash结构的一个字段,字段名为Item类型,字段值为Item数据的序列化形式(如JSON字符串)。通过Hash结构的存储方式,可以方便地组织和管理多个Item,并且保持数据结构的完整性。

针对这些解决方案,需要在Item Pipeline中实现相应的逻辑。根据不同的场景和需求,选择最适合的方案进行实现。同时,在Spider中生成不同类型的Item时,确认将其传递到对应的Pipeline中进行处理和存储。

案例分析:

当一个Scrapy-Redis爬虫有多个不同的Items,并且希望将这些Items最后存储到SQL数据库中,按照表格进行划分,可以按照以下步骤完成:

创建不同类型的Items: 首先,创建5个不同的Items,分别对应于要存储到SQL数据库中的不同表格。确保每个Item都有与之对应的字段,以便正确存储数据。
import scrapy


class ItemA(scrapy.Item):
    # Item A的字段
    field_a1 = scrapy.Field()
    field_a2 = scrapy.Field()
    ...


class ItemB(scrapy.Item):
    # Item B的字段
    field_b1 = scrapy.Field()
    field_b2 = scrapy.Field()
    ...


# 定义其他的Items (ItemC, ItemD, ItemE)
编写Pipeline进行数据存储: 创建一个自定义的Pipeline类,用于将爬取到的每个Item存储到相应的表格中。在Pipeline中实现process_item方法,在该方法中根据Item类型的不同,将数据存储到对应的表格中。
import pymysql

class SQLPipeline(object):

    def open_spider(self, spider):
        # 初始化连接数据库的操作
        self.connection = pymysql.connect(
            host='localhost',
            user='your_username',
            password='your_password',
            db='your_database'
        )
        self.cursor = self.connection.cursor()

    def close_spider(self, spider):
        # 在爬虫结束时关闭数据库连接
        self.cursor.close()
        self.connection.close()

    def process_item(self, item, spider):
        if isinstance(item, ItemA):
            self.save_to_table_a(item)
        elif isinstance(item, ItemB):
            self.save_to_table_b(item)
        # 处理其他Items (ItemC, ItemD, ItemE)

    def save_to_table_a(self, item):
        # 将Item A的数据存储到对应的表格
        sql = "INSERT INTO table_a (field_a1, field_a2) VALUES (%s, %s)"
        values = (item['field_a1'], item['field_a2'])
        self.cursor.execute(sql, values)
        self.connection.commit()

    def save_to_table_b(self, item):
        # 将Item B的数据存储到对应的表格
        sql = "INSERT INTO table_b (field_b1, field_b2) VALUES (%s, %s)"
        values = (item['field_b1'], item['field_b2'])
        self.cursor.execute(sql, values)
        self.connection.commit()

    # 实现其他的存储方法 (save_to_table_c, save_to_table_d, save_to_table_e)
配置Pipeline: 在Scrapy的配置文件(settings.py)中,将创建的Pipeline类加入到ITEM_PIPELINES设置中,并根据需要设置其优先级。确保该Pipeline的优先级较高,以便在数据存储时被优先调用。
ITEM_PIPELINES = {
    'myproject.pipelines.SQLPipeline': 300,
    # 其他的Pipeline
}
启动爬虫: 在主程序中启动爬虫,使用Scrapy提供的CrawlerProcess来创建Crawler实例,并指定要运行的爬虫和相关设置。
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from myproject.spiders import MySpider

# 将爬虫和相关设置传递给CrawlerProcess
process = CrawlerProcess(get_project_settings())
process.crawl(MySpider)
process.start()

将Scrapy-Redis爬虫中的多个不同的Items按照表格的形式存储到SQL数据库中。通过自定义Pipeline来处理每个Item并将其存储到相应的表格中,实现数据的持久化存储。

文章来源:https://blog.csdn.net/m0_56758840/article/details/135736700
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。