一、基于终端指令的持久化存储

  保证爬虫文件的parse方法中有可迭代类型对象(通常为列表or字典)的返回,该返回值可以通过终端指令的形式写入指定格式的文件中进行持久化操作。

# 执行输出指定格式进行存储:将爬取到的数据写入不同格式的文件中进行存储
scrapy crawl 爬虫名称 -o xxx.json
scrapy crawl 爬虫名称 -o xxx.xml
scrapy crawl 爬虫名称 -o xxx.csv

二、基于管道的持久化存储

  scrapy框架中已经为我们专门集成好了高效、便捷的持久化操作功能,我们直接使用即可。要想使用scrapy的持久化操作功能,我们首先来认识如下两个文件:

  items.py:数据结构模板文件。定义数据属性。

  pipelines.py:管道文件。接收数据(items),进行持久化操作。

持久化流程:

1.爬虫文件爬取到数据后,需要将数据封装到items对象中。

2.使用yield关键字将items对象提交给pipelines管道进行持久化操作。

3.在管道文件中的process_item方法中接收爬虫文件提交过来的item对象,然后编写持久化存储的代码将item对象中存储的数据进行持久化存储

4.settings.py配置文件中开启管道

三、项目实战(糗事百科)

  爬虫文件:qiubaiDemo.py

import scrapy
from secondblood.items import SecondbloodItem

class QiubaidemoSpider(scrapy.Spider):
    name = 'qiubaiDemo'
    # 允许的访问域
    #allowed_domains = ['www.qiushibaike.com']
    start_urls = ['http://www.qiushibaike.com/']

    # 数据解析
    def parse(self, response):
        odiv = response.xpath('//div[@>)
        for div in odiv:
            # xpath函数返回的为列表,列表中存放的数据为Selector类型的数据。我们解析到的内容被封装在了Selector对象中,需要调用extract()函数将解析的内容从Selecor中取出。
            author = div.xpath('.//div[@class="author clearfix"]//h2/text()').extract_first()
            author = author.strip('\n')#过滤空行
            content = div.xpath('.//div[@class="content"]/span/text()').extract_first()
            content = content.strip('\n')#过滤空行

            #将解析到的数据封装至items对象中
            item = SecondbloodItem()
            item['author'] = author
            item['content'] = content

            yield item#提交item到管道文件(pipelines.py)

  items文件:items.py

import scrapy

class SecondbloodItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    # 创建类的静态属性,存放解析的数据
    author = scrapy.Field() #存储作者
    content = scrapy.Field() #存储段子内容

  管道文件:pipelines.py

  • open_spider(self, spider) -- > 只执行一次,一般创建文件句柄或者创建数据库连接
  • process_item(self, item,spider) -- > 数据的持久化存储
  • close_spider(self, spider) -- > 只执行一次,一般用于关闭文件句柄等
import pymysql
from redis import Redis


# 持久化数据到mysql
class QiubaiproPipeline(object):
    # 创建sql连接
    conn = None
    # 创建sql游标
    cursor = None

    # 爬虫开始执行,创建mysql连接
    def open_spider(self, spider):
        self.conn = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="1234", db="spider")

    # 持久化存储
    def process_item(self, item, spider):
        # 创建游标
        self.cursor = self.conn.cursor()
        # 获取数据属性
        author = item["author"]
        content = item["content"]
        print(author, content)
        sql = "insert into qiushipro values('%s','%s')"%(author, content)

        try:
            # 执行sql语句
            self.cursor.execute(sql)
            # 事务提交
            self.conn.commit()
        except Exception as e:
            # 打印错误信息
            print(e)
            # 事务回滚
            self.conn.rollback()

        self.cursor.close()
        # 返回item对象到管道,供下一个管道类接收
        return item

    # 关闭数据库游标与连接
    def close_spider(self, spider):
        # self.cursor.close()
        self.conn.close()


# 持久化数据到redis
class RedisPipeline(object):
    # 创建redis连接
    conn = None

    # 爬虫开始执行,创建mysql连接
    def open_spider(self, spider):
        self.conn = Redis(host="127.0.0.1", port=6379, db=0)

    # 持久化存储
    def process_item(self, item, spider):
        # 获取数据属性
        author = item["author"]
        content = item["content"]

        # 创建存储的数据结构
        data = {
            "author": author,
            "content": content
        }

        # 在redis数据库中创建一个键为qiushibaike的队列,值为一个列表,由左向右压栈
        self.conn.lpush("qiushibaike", data)

        # 返回item对象到管道,供下一个管道类接收
        return item

  配置文件:settings.py

# 开启管道
ITEM_PIPELINES = {
   'qiubaiPro.pipelines.QiubaiproPipeline': 300,  #优先级 数字越小,优先级越高,越先执行
   'qiubaiPro.pipelines.RedisPipeline': 400,
}