引入

Scrapy的数据持久化,主要包括存储到数据库、文件以及内置数据存储。

那我们今天就来讲讲如何把Scrapy中的数据存储到数据库和文件当中。

终端指令存储

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

# 执行输出指定格式进行存储:将爬取到的数据写入不同格式的文件中进行存储
scrapy crawl 爬虫名称 -o xxx.json # 存为json文件
scrapy crawl 爬虫名称 -o xxx.xml # 存为xml文件
scrapy crawl 爬虫名称 -o xxx.csv # 存为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[@id="content-left"]/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.py(items文件)

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(管道文件)

class SecondbloodPipeline(object):
# 构造方法
def __init__(self):
self.fp = None # 定义一个文件描述符属性
# 下列都是在重写父类的方法:
# 开始爬虫时,执行一次
def open_spider(self,spider):
print('爬虫开始')
self.fp = open('./data.txt', 'w')    # 因为该方法会被执行调用多次,所以文件的开启和关闭操作写在了另外两个只会各自执行一次的方法中。
def process_item(self, item, spider):
# 将爬虫程序提交的item进行持久化存储
self.fp.write(item['author'] + ':' + item['content'] + '\n')
return item # 结束爬虫时,执行一次
def close_spider(self,spider):
self.fp.close()
print('爬虫结束')

- settings.py(配置文件)

# 开启管道
ITEM_PIPELINES = {
'secondblood.pipelines.SecondbloodPipeline': 300, # 300表示为优先级,值越小优先级越高
}

基于mysql的管道存储

在管道文件里将item对象中的数据值存储到了磁盘中,如果将item数据写入mysql数据库的话,只需要将上述案例中的管道文件修改成如下形式:

- pipelines.py

# 导入数据库的类
import pymysql
class QiubaiproPipelineByMysql(object): conn = None # mysql的连接对象声明
cursor = None # mysql游标对象声明
def open_spider(self,spider):
print('开始爬虫')
# 链接数据库
self.conn = pymysql.Connect(host='127.0.0.1',port=3306,user='root',password='',db='qiubai')
# 编写向数据库中存储数据的相关代码
def process_item(self, item, spider):
# 1.链接数据库
# 2.执行sql语句
sql = 'insert into qiubai values("%s","%s")'%(item['author'],item['content'])
self.cursor = self.conn.cursor()
# 执行事务
try:
self.cursor.execute(sql)
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback() return item
def close_spider(self,spider):
print('爬虫结束')
self.cursor.close()
self.conn.close()

- settings.py

ITEM_PIPELINES = {
'qiubaiPro.pipelines.QiubaiproPipelineByMysql': 300,
}

基于redis的管道存储

在管道文件里将item对象中的数据值存储到了磁盘中,如果将item数据写入redis数据库的话,只需要将上述案例中的管道文件修改成如下形式:

- pipelines.py

import redis

class QiubaiproPipelineByRedis(object):
conn = None
def open_spider(self,spider):
print('开始爬虫')
# 创建链接对象
self.conn = redis.Redis(host='127.0.0.1',port=6379)
def process_item(self, item, spider):
dict = {
'author':item['author'],
'content':item['content']
}
# 写入redis中
self.conn.lpush('data', dict)
return item

- settings.py

ITEM_PIPELINES = {
'qiubaiPro.pipelines.QiubaiproPipelineByRedis': 300,
}

抛出需求

如果最终需要将爬取到的数据值一份存储到磁盘文件,一份存储到数据库中,则应该如何操作scrapy?

# 该类为管道类,该类中的process_item方法是用来实现持久化存储操作的。
class DoublekillPipeline(object): def process_item(self, item, spider):
#持久化操作代码 (方式1:写入磁盘文件)
return item #如果想实现另一种形式的持久化操作,则可以再定制一个管道类:
class DoublekillPipeline_db(object): def process_item(self, item, spider):
# 持久化操作代码 (方式1:写入数据库)
return item

pipelines.py

# 下列结构为字典,字典中的键值表示的是即将被启用执行的管道文件和其执行的优先级。
ITEM_PIPELINES = {
'doublekill.pipelines.DoublekillPipeline': 300,
'doublekill.pipelines.DoublekillPipeline_db': 200,
} # 上述代码中,字典中的两组键值分别表示会执行管道文件中对应的两个管道类中的process_item方法,实现两种不同形式的持久化操作。

settings.py

论Scrapy中的数据持久化的更多相关文章

  1. iOS中的数据持久化方式

    iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data. 1.属性列表 涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults ...

  2. IOS学习:ios中的数据持久化初级(文件、xml、json、sqlite、CoreData)

    IOS学习:ios中的数据持久化初级(文件.xml.json.sqlite.CoreData) 分类: ios开发学习2013-05-30 10:03 2316人阅读 评论(2) 收藏 举报 iOSX ...

  3. Android中的数据持久化机制

    Android中几种最简单但是却最通用的数据持久化技术:SharedPreference.实例状态Bundle和本地文件. Android的非确定性Activity和应用程序生存期使在会话间保留UI状 ...

  4. Redis 中的数据持久化策略(RDB)

    Redis 是一个内存数据库,所有的数据都直接保存在内存中,那么,一旦 Redis 进程异常退出,或服务器本身异常宕机,我们存储在 Redis 中的数据就凭空消失,再也找不到了. Redis 作为一个 ...

  5. Redis 中的数据持久化策略(AOF)

    上一篇文章,我们讲的是 Redis 的一种基于内存快照的持久化存储策略 RDB,本质上他就是让 redis fork 出一个子进程遍历我们所有数据库中的字典,进行磁盘文件的写入. 但其实这种方式是有缺 ...

  6. 工作流中的数据持久化详解!Activiti框架中JPA的使用分析

    Activiti中JPA简介 可以使用JPA实体作为流程变量, 并进行操作: 基于流程变量更新已有的JPA实体,可以在用户任务的表单中填写或者由服务任务生成 重用已有的领域模型,不需要编写显示的服务获 ...

  7. iOS开发中的4种数据持久化方式【一、属性列表与归档解档】

    iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...

  8. iOS中常用的四种数据持久化技术

    iOS中的数据持久化方式,基本上有以下四种:属性列表 对象归档 SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 [NSUserDefaults st ...

  9. iOS中常用的四种数据持久化方法简介

    iOS中常用的四种数据持久化方法简介 iOS中的数据持久化方式,基本上有以下四种:属性列表.对象归档.SQLite3和Core Data 1.属性列表涉及到的主要类:NSUserDefaults,一般 ...

随机推荐

  1. Elasticsearch.Net、Nest批量插入BulkAll

    demo地址:BulkAll 批量导入 实现目标:想要使用ElasticSearch的 .Net Api客户端NEST批量导入数据,并发异步高效的批量导入 NEST提供了BulkAll 不废话,上代码 ...

  2. oracle学习笔记(五) SQL操作符

    SQL操作符 算术操作符:+加,-减,*乘,/除 比较操作符: <,>,=,!=,<>,<=,>= 常用的判断,<>和!=相同 between $low ...

  3. ideal中spring的xml文件没有提示的问题

    ideal中spring的xml文件没有提示的问题 今天第一次用ideal来练习spring,发现和视频中老师不一样,我的没有提示.老师的视频里,他写了个<mvc:a   就会有一系列的提示,然 ...

  4. Vue 无限滚动加载指令

    也不存在什么加载咯, 就是一个判断滚动条是否到达浏览器底部了. 如果到了就触发事件,米到就不处理. 计算公式提简单的   底部等于(0) =  滚动条高度 - 滚动条顶部距离 - 可视高度.  反正结 ...

  5. composer windows下安装

    composer windows安装  因要使用PhpSpreadsheet处理excel表格 选择composer安装 1. 下载Composer-Setup.exe 2.点击直接运行---选择ph ...

  6. 学习笔记—JDBC

    JDBC的概念 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言 ...

  7. NextCloud前端支持播放mov文件

    默认情况下,NextCloud网盘是不支持播放 .mov文件的. 通过修改前端代码就可以实现. 如下 1 找到 apps/files_videoplayer/js/viewer.js 文件 2 搜索 ...

  8. Android 字体适配方案

    开发过程中,按照UI设计尺寸做好UI页面,当用户自定义自己的手机字体大小之后UI完全没法看了,这个时候就在想让app字体大小始终一致就好了 下面看一下,出现的问题和解决方案     做个简单的例子,先 ...

  9. Android Studio打包SDK后,为什么没有bundles文件夹?

    在Android Studio中,将项目打包成jar包,按照网上说的方法打包完成后,在intermediates文件夹下没有bundles,AS版本3.1.2,后来发现,原来是intermediate ...

  10. 这20个常规Python语法你都搞明白了吗?

    Python简单易学,但又博大精深.许多人号称精通Python,却不会写Pythonic的代码,对很多常用包的使用也并不熟悉.学海无涯,我们先来了解一些Python中最基本的内容. Python的特点 ...