处理Redis中的数据
我们通过分布式爬虫抓取的网页数据,默认会全部保存在Redis数据库中。每次启动Redis库时,它都会将本机之前存储的数据加载到内存中,如果数据信息很大,则内存消耗会比较严重。因此,我们需要将数据从Redis数据库里面取出来,另外对其进行持久化存储。
一般来说,数据的持久化存储有两种方式:MongoDB和MySQL。由于Python和MongoDB的交互比较便捷,所以这里选择以MongoDB进行存储。
为了达到这个目的,我们可以额外编写一个脚本,单独负责将Redis中的数据转移到MongoDB中。这个脚本可以跟爬虫同步执行,它不会受到Scrapy框架的影响,只是单纯地从Redis数据库中取数据。
创建一个Python File文件,取名为process_aqi_profile,该文件的具体代码如下。
# -*- coding: utf-8 -*-
import json
import redis
import pymongo
def main():
# 指定Redis数据库信息
redis_cli = redis.Redis(host='192.168.88.94', port=6379, db=0)
# 指定MongoDB数据库信息
mongo_cli = pymongo.MongoClient(host='127.0.0.1', port=27017)
# 创建数据库名
db = mongo_cli['aqi']
# 创建表名
sheet = db['aqi_data']
while True:
# FIFO模式为 blpop,LIFO模式为 brpop,获取键值
source, data = redis_cli.blpop(["aqi:items"])
item = json.loads(data)
sheet.insert(item)
try:
print u"Processing: %(name)s <%(link)s>" % item
except KeyError:
print u"Error procesing: %r" % item
if __name__ == '__main__':
main()
上述代码中,在main函数中分别创建了Redis和MongoDB数据库的连接,然后创建了数据库和表,接着按照先进先出的模式,使用while循环一直从Redis中取数据。
取到的数据是“aqi:items”,冒号前面是爬虫名,冒号后面是爬虫数据,对应着Redis中的数据“aqi:items”。
blpop方法返回两个值:source和data。其中,source表示爬虫名,data表示Item数据。data是一个字典,需要通过json模块将其转换为Python格式后,插入到MongoDB中。
最后,在程序的入口中调用main函数。
在终端中使用如下命令启动MongoDB,具体如下:
sudo mongod
运行上述程序,可以看到Redis数据库中的数据已经转移到MongoDB中。
值得一提的是,这个脚本和爬虫项目是不冲突的,只要Redis中存入一条数据,就将其取出来插入到MongoDB中。因此,在爬虫启动后,这个脚本会在后台单独运行,我们无需管它何时结束,只要Redis里面没有数据了,就会让它自己关闭。