Logo

郎哥编程

存储爬取数据的Pipeline管道类

2020-12-11 331

1、 初识Pipeline管道类

Pipeline管道类用于处理爬虫爬取的的Item数据,Item数据装配完成后,会提交给Pipeline管道类,Pipeline管道类会对Item数据进一步处理,包括数据的清洗、验证和存储。Pipeline管道类最终会决定爬取的Item数据是否保留或放弃。

018.png

爬虫提取的Item数据可以直接提交给Pipeline管道类,也可以通过ItemLoader类处理后再提交给Pipeline管道类。

Pipeline管道类会对Item数据进一步处理,包括数据的清洗和验证。若Item数据有问题,可以直接放弃该数据;若Item数据没有问题,则存储Item数据,可以以多种方式存储Item数据,根据爬虫的目的和需求,可以将Item数据存储到数据库,也可以存储为JSON数据或其它数据格式。

项目创建后,Scrapy框架会自动创建一个管道类,模块名称是pipelines.py,该管道类对Item数据不做任何处理,直接返回Item数据。pipelines.py代码如下:

from itemadapter import ItemAdapter
class NewsbaiduPipeline:
    def process_item(self, item, spider):
        return item

从给出的代码也可以看出,NewsbaiduPipeline管道类对传入的Item数据不做任何处理,直接返回Item。若程序需要验证Item数据或存储到数据库,可以在这里添加相关代码。

Pipeline管道类是一个独立的Python类,该类必须实现下面的方法:

process_item(self, item, spider)

该方法用于处理传入的item数据项,并且必须返回一个Item对象,或者是处理后的Item对象,或者直接返回原item对象。若该方法没有返回Item对象,后续的Pipeline管道类将停止处理Item对象。

参数item是传入的Item实例对象。

参数spider是爬虫实例对象。

另外,Pipeline管道类也可以实现下面的三个方法:

open_spider(self, spider)

当爬虫启动时,该方法被调用。若程序需要在爬虫启动时,对Pipeline管道类进行初始化,可以在该方法内部进行。

close_spider(spider)

当爬虫关闭时,该方法被调用。若程序需要在爬虫关闭时,对管道类使用的资源做释放处理时,可以在该方法内部进行。

2、ItemAdapter适配器类

Scrapy默认创建的Pipeline管道类文件pipelines.py,使用到了ItemAdapter适配器类,ItemAdapter类是数据容器对象的包装器,它提供了一个公共接口以以适配不同类型的对象,而不管它们的底层实现如何。

ItemAdapter类主要支持dict字典对象和Scrapy Item数据对象的适配。

ItemAdapter类的构造方法如下表所示:

019.png

ItemAdapter实例对象可以像字典一样处理,字典的操作方法都可以用于ItemAdapter实例对象。另外,ItemAdapter实例对象也提供了下面的操作方法:

020.png

3、 启动Pipeline管道

Scrapy创建的爬虫项目包含了一个默认的Pipeline模块文件,模块文件名称是pipelines.py,该管道默认是关闭的,爬取数据的处理流程并不包括该管道。若启动该管道,需要修改配置文件ITEM_PIPELINES配置项,默认配置文件中ITEM_PIPELINES配置项是被注释掉的,把相关语句的注释去掉:

ITEM_PIPELINES = {
   'newsbaidu.pipelines.NewsbaiduPipeline': 300,
}

ITEM_PIPELINES配置项的值是字典对象,字典对象的每个元素是一个Pipeline管道类,可以添加多个Pipeline管道类。key是Pipeline管道类的类名称,value是一个整数,该整数确定了多个Pipeline管道类的运行顺序,Item数据将按照运行顺序依次被处理。通常将这些数字定义在0-1000范围内(0-1000随意设置,数值越低,对应的Pipeline管道类的运行顺序越靠前)。

在Pipeline管道类处理链中,链中的任一Pipeline管道类若没有返回处理后的Item数据项,Scrapy将停止处理Item数据项。

4、  项目输出CSV文件

Pipeline管道类NewsbaiduPipeline对Item数据不做任何处理,原样返回Item数据。

现在修改NewsbaiduPipeline类代码,将爬取的数据输出为CSV文件。

案例代码如下:

from itemadapter import ItemAdapter
# 导入csv模块
import csv
# 导入os模块
import os
class NewsbaiduPipeline:
  
    # 定义构造方法,打开CSV文件
    def __init__(self):
 
        # 定义CSV文件的存储路径
        store_file = os.path.dirname(__file__) + '/items.csv'
        # 以a+模式创建CSV文件
        self.file = open(store_file,'a+',newline='')
        # 实例化writer对象
        self.writer = csv.writer(self.file)
       
    def process_item(self, item, spider):
 
        # 获得item数据项适配器
        adapter = ItemAdapter(item)
        if adapter:
            # row为列表对象
            row = [adapter['news_title'][0],adapter['news_link'][0]]
            # row写入CSV文件
            self.writer.writerow(row)
        return item
       
    # 爬虫程序关闭时,该方法被调用
    def close_spider(self,spider):
        # 关闭文件
        self.file.close()

案例代码添加了构造方法__init__,在构造方法内部实例化CSV文件对象及csv模块的Writer实例对象。

案例代码重写了process_item方法,在方法内部获得item适配对象adapter,若adapter不为空,应用adapter适配对象构造列表对象,最后调用writer对象的writerow方法将item数据写入CSV文件。

案例代码添加了close_spider方法,该方法在爬虫关闭时被调用,当爬虫关闭时,关闭打开的CSV文件。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论