美文网首页
你知道在 scrapy 中,可以定制化导出数据格式吗?scrap

你知道在 scrapy 中,可以定制化导出数据格式吗?scrap

作者: 梦想橡皮擦 | 来源:发表于2022-02-17 09:16 被阅读0次

本篇博客将系统的复习一下 scrapy 保存数据相关内容,即 导出器(Exporter)相关知识。

使用 Exporter 导出数据

编写 scrapy 爬虫是非常便捷的,而且可以快速的保存采集的结果,只需要运行爬虫时,在命令行输入如下代码:

scrapy crawl 爬虫文件名 -o 保存文件名

在 Scrapy 中,导出数据的中间件叫做 Exporter,即导出器,它内置了 6 种可导出格式,分别是 JSONJSON LINESCSVXMLPickleMatshal

一般使用上述的内置格式,就可以满足各种场景需求了。
在存储的时候,只需要在命令行下输入 -o 文件名.后缀,即可基于文件后缀名区分存储文件格式。

也可以通过 -t 文件类型 进行格式的选择,例如下述命令行:

scrapy crawl 爬虫名称 -t csv -o mydata.data

Scrapy 项目的全局配置default_settings.py 文件中,关于导出器的配置如下,其中可以看到内置的 6 种导出器,并且它们都在 scrapy.exporters 模块中。

FEED_EXPORTERS = {}
FEED_EXPORTERS_BASE = {
    'json': 'scrapy.exporters.JsonItemExporter',
    'jsonlines': 'scrapy.exporters.JsonLinesItemExporter',
    'jl': 'scrapy.exporters.JsonLinesItemExporter',
    'csv': 'scrapy.exporters.CsvItemExporter',
    'xml': 'scrapy.exporters.XmlItemExporter',
    'marshal': 'scrapy.exporters.MarshalItemExporter',
    'pickle': 'scrapy.exporters.PickleItemExporter',
}
FEED_EXPORT_INDENT = 0

因为导出格式可以配置,所以我们也可以编写定制化的导出器,添加到 scrapy 中使用。

编写爬虫实现导出器实操

本次直接进入案例实操环节,用于解释导出器相关使用技巧。

爬虫文件代码

import scrapy


class YySpider(scrapy.Spider):
    name = 'yy'
    allowed_domains = ['pharmnet.com.cn']
    start_urls = ['http://www.pharmnet.com.cn/product/1111/1/1.html']

    def parse(self, response):
        all_items = response.css('a.green.fb.f13::text').getall()
        for item in all_items:
            yield {
                "name": item
            }

运行爬虫可以使用下述两个命令,都可以获取到 CSV 文件。

scrapy crawl yy -o data.csv
scrapy crawl yy -t csv -o data.d

在导出文件时,还可以使用两个特殊参数,如下所示:

scrapy crawl yy -t csv -o data/%(name)s/%(time)s.csv

其中 %(name)s 对应爬虫名字,%(time)s 对应文件创建时间。

如果不想在导出文件的时候,通过命令进行配置,可以将这些内容写到 settings.py 文件中,这里用到的配置字段是 FEEDS

FEEDS = {
    'items.csv': {
        'format': 'csv',
        'encoding': 'utf8',
    },
}

该配置是字典类型,键名就是文件名,键值是文件的具体配置,常用内容如下所示:

  • format:导出类型,就是内置的几种类型;
  • batch_item_count:如果设置了一个整数,表示每个文件存储的数据条目,scrapy 会生成多个文件,设置了该值还要设置一个文件名生成规则,代码在下面;
  • encoding:编码;
  • fields:展示的字段;
  • indent:每一层用于缩进的空格数量;

batch_item_count 相关规则,其中 %(batch_time)s 获取时间戳,%(batch_id)d 获取序号。

FEEDS = {
    '%(batch_id)d.csv': {
        'format': 'csv',
        'encoding': 'utf8',
        'batch_item_count': 2,
    },
}

default_settings.py 中有哪些与 FEEDS 相关的配置,可以查看下述内容。

FEED_TEMPDIR = None
FEEDS = {}
FEED_URI_PARAMS = None  # a function to extend uri arguments
FEED_STORE_EMPTY = False
FEED_EXPORT_ENCODING = None
FEED_EXPORT_FIELDS = None
FEED_STORAGES = {}

自己实现一个导出器

如果 scrapy 内置的 6 种导出器无法满足要求,就可以自定义一个导出器。
实现方式非常简单,只需要在导出器类中,实现基类 BaseItemExporter 的接口即可。

自定义导出器主要涉及如下三个方法。

  • start_exporting():导出器的初始化方法;
  • finish_exporting():导出器结束时调用的方法;
  • export_item():核心方法,对 item 中的每一项导出时,都会执行。

接下来我们就实现一个自己定义的导出器。

settings.py 文件同级目录创建一个 my_ext.py 文件,然后创建一个 TXTItemExporter 类,其继承 BaseItemExporter

其余代码如下所示:

from scrapy.exporters import BaseItemExporter


class TXTItemExporter(BaseItemExporter):

    def __init__(self, file, **kwargs):
        super().__init__(dont_fail=True, **kwargs)
        self.file = file

    def export_item(self, item):
        # _get_serialized_fields 方法可以获得 item 所有字段,并返回迭代器
        print(self._get_serialized_fields(item, default_value=''))
        print(self.file)
        for name, value in self._get_serialized_fields(item, default_value=''):
            self.file.write(bytes("\nname:" + value, encoding="utf-8"))

本篇博客的案例计划是采集网站 http://www.pharmnet.com.cn/,但由于其是一个医药平台,不好过审,所以大家自行采集吧。

你知道在 scrapy 中,可以定制化导出数据格式吗?scrapy 导出器学习

写在后面

今天是持续写作的第 <font color=red>257</font> / 365 天。
期待 <font color=#04a9f4>关注</font>,<font color=#04a9f4>点赞</font>、<font color=#04a9f4>评论</font>、<font color=#04a9f4>收藏</font>。

更多精彩

《爬虫 100 例,专栏销售中,买完就能学会系列专栏》

你知道在 scrapy 中,可以定制化导出数据格式吗?scrapy 导出器学习

<center>
👇👇👇扫码加入【78技术人社群】~ Python 事业部👇👇👇,源码也在这</center>

相关文章

网友评论

      本文标题:你知道在 scrapy 中,可以定制化导出数据格式吗?scrap

      本文链接:https://www.haomeiwen.com/subject/iibjlrtx.html