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

news/2024/7/19 9:31:23 标签: 爬虫, scrapy

前言:

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并将其存储到相应的表格中,实现数据的持久化存储。


http://www.niftyadmin.cn/n/5339069.html

相关文章

vectorCast手动添加测试用例配置输入参数和期望值

1.选中函数,点击右键选择插入测试用例。这里所选择的插入测试用例区别于之前的测试用例的地方在于,这里插入测试用例是手动配置的,之前的是自动生成的。手动配置可以自定义选择输入参数和期望值。 2.添加测试用例后,点击测试用例&…

[学习笔记]刘知远团队大模型技术与交叉应用L4-Prompt-learning Delta-learning

Prompt-Learning and Delta-Tunning 背景和概览 但是从T5开始,大模型越来越大了。 微调很难了。 模型的趋势 Model Scaling:模型越来越大 Difficult Tuning:微调越来越难 Prompt-Learning 基本组成与流程介绍 预训练和fine-tuning有一…

读元宇宙改变一切笔记12_元宇宙+

1. 元宇宙的价值 1.1. 元宇宙的价值,将“超过”物理世界 1.2. 移动互联网时代不是突然降临的 1.2.1. 我们可以确定一项特定的技术是何时被创造、测试或部署的,但不能确定一个时代何时开始或何时结束 1.2.2. 转型是一个迭代的过程,在这个过…

5G_系统同步机制(八)

BBU和RRU的同步机制 为什么要做到系统同步 在TDD模式下工作时,为了避免相邻小区之间的干扰,近距离的所有gNB在任何时间点都必须具有相同的传输方向(DL或UL)。这样做的必要条件是在BTS之间同步SFN (System Frame number)和time Slot。此外,由…

Python 算法交易实验67 第一次迭代总结

说明 在这里对第一次迭代(2023.7~ 2024.1)进行一些回顾和总结: 回顾: 1 实现了0~1的变化2 在信息隔绝的条件下,无控制的操作,导致被套 总结: 思路可行,在春暖花开的时候&#x…

vmware 安装Rocky-9.3系统

安装系统截图 安装完成,启动 查看版本和内核 开启远程登陆授权 1、编辑配置文件 #提升权限,输入su,并输入密码 su #编辑ssh文件开启root远程登陆 vi /etc/ssh/sshd_config找到以下内容:#PermitRootLogin prohibit-password 添加&#xff1a…

【QT+QGIS跨平台编译】之一:【sqlite+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、sqlite3介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、sqlite3介绍 SQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的&…

【OCR项目】之用HALCON的深度学习工具进行文字识别,并导出到C++调用

前言 HALCON是一个强大的机器视觉工具,包含了2D,3D图像各种算子,以及各种任务的深度学习工具,包括目标检测,实例分割,文字识别等。 这次从实际生产的角度,来分享一下如何用HALCON进行文字识别…