引入

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. Ajax全局处理错误

    背景:项目前端ajax请求很多都没有写error方法,所以用户体验很不好 新来的前端负责人发现这个问题,写了一个错误处理方法,如下 //统一处理Ajax错误方法 function onAjaxErro ...

  2. javascript 函数后面有多个小括号f( )( )( )...

    有时我们看见js函数后面跟着多个小括号是什么意思?f( )( )( )... f()执行f函数,返回子函数 f()()执行子函数,返回孙函数 f()()()执行孙函数,返回重孙函数 ... ... 但 ...

  3. Ext.isIterable

    Ext.isIterable用于判断传入的参数是否为可迭代的 在这4种情况下,函数返回true 1:数组2:函数参数arguments3:HTML collections : NodeList4:HT ...

  4. Doctype的作用?严格模式与混合模式,如何触发者这两种模式,区分它们有何意义?

    Doctype作用?严格模式与混合模式,如何触发者这两种模式,区分它们有何意义? 1.1 Doctype作用 <!DOCTYPE>声明叫做文件类型定义(DTD),声明的作用为了告诉浏览器该 ...

  5. SAP HUM 拆包之后的HU号码依旧存在

    比如HU 194811210666,已经被执行了Unpack操作. HUMO看这个HU号码, 执行, 可以发现,这个HU是空的,里面什么都没有. 双击HU号码,进入HU显示界面, 系统状态竟然是PHE ...

  6. vmware完整克隆(linux)

    vmware中的完整克隆是基于指定的虚拟机克隆出相同的一份出来,不必再安装 但是我们要保证三个地方不能一样,一个是主机名称(hostname),一个是虚拟网卡设备mac地址,还有一个是ip地址 所以我 ...

  7. Python 小试牛刀,Django详细解读,让你更快的掌握它!!!

    一.MVC和MTV模式 MVC:将web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业务对象与数据库的对象(ORM),视图负责与用户的交 ...

  8. 2 OpenWrt路由器系统开发与网页设计

    https://www.zhongkerd.com/news/content-729.html 摘 要: 目前商用WiFi路由器已应用到多个领域,商家通过给用户提供一个稳定免费WiFi热点达到吸引客户 ...

  9. 用div画三角/矩形/圆

    1. 画三角 <!DOCTYPE html> <html> <head> <title></title> <meta charset= ...

  10. 小小知识点(十三)——MATLAB中怎么保存和读取.mat文件

    1.存储 利用save函数 save(filename)  %将当前工作区中的所有变量保存在 MATLAB® 格式的二进制文件(MAT 文件)filename 中. save(filename,var ...