MongoDB与Redis

MongoDB

数据库,用来保存大量数据

数据在MongpDB中是按照库(Database) - 集合(Collections) - 文档(Document)的层级关系来存储的。

文档 字典

集合 包含很多字典的列表

MongoDB的增删改查

pymongo

在安装完MongoDB之后再安装pymongo

import pymongo

连接/创建数据库

from pymongo import MongoClient

# 建立连接
# client = MongoClient("localhost", 27017)
# client = MongoClient("mongodb://localhost:27017/"")
client = MongoClient()

# 指定要进行操作的databse和collection
# database = client.Chapter6
# collection = database.spider
database = client['Chapter6']
collection = database['spider']

插入数据

  • insert_one 插入文档
  • insert_many 插入集合
# 写入数据
data1 = {'id': 123, 'name': 'kingname', 'age': '20', 'salary': '9999'}
collection.insert_one(data1)

data2 = [{'id': 123, 'name': 'kingname', 'age': '20', 'salary': '9999'}, {'id': 124, 'name': 'kingname', 'age': '20', 'salary': '9999'}]
collection.insert_many(data2)

data3 = []
data3.append(data1)
collection.insert_many(data3)

mongoDB会自动添加一列_id,里面的数据叫做ObjectId, ObjectId是在数据被插入mongoDB的瞬间,通过一定算法计算出来的。因此,_id这一列就代表数据插入的时间,它不重复,而且始终递增,通过一定的算法,可以把ObjectId反向恢复为时间

删除数据

  • delete_one 删除一条数据 参数为字典
  • delete_many 删除多条数据 参数为字典

修改数据

  • replace_one
  • update_one:该方法第一个参数为查询的条件,第二个参数为要修改的字段。 只能修改匹配到的第一条记录。
  • update_many :该方法第一个参数为查询的条件,第二个参数为要修改的字段。 修改匹配到的所有记录。
import pymongo
from pymongo import MongoClient
client = MongoClient()
database = client['Chapter6']
collection = database['spider']

# 修改数据
query_condition = {'age': 20}
new_value = {"$set": {'name': '叶敬平'}}
collection.update_one(query_condition, new_value)

# update_many
myquery = {"id":  123}
newvalues = {"$set": {"salary": 9000}}
collection.update_many(myquery, newvalues)

查询数据

普通查询
  • find 返回满足条件的集合
  • find_one 返回满足条件的文档
from pymongo import MongoClient
client = MongoClient()
database = client['Chapter6']
collection = database['spider']

content1 = collection.find_one({'id':123})
print(content1)

content2 = collection.find({'id': 123})
for i in content2:
    print(i)

去重查询结果

collection.distinct('列名')

Redis

作为缓存和队列保存临时数据。基于内存的数据库,速度快于MongDB

设计一个开关,实现在不结束程序进程的情况下,从全世界任何一个有网络的地方既能随时暂停程序,又能随时恢复程序的运行。

操作列表

redis的列表是一个可读可写的双向队列,可以把数据从左侧或者右侧插入到列表中,也可以从左侧或者右侧读出数据,还可以查看列表的长度。

# 左侧写入数据
lpush key value1 value2 value3 
# 左侧读取数据并从列表删除
lpop chapter_6
# 右侧写入数据
rpush key valu1 value2 value3
# 右侧读取数据并从列表删除
rpop chapter_6
# 查看列表的长度
llen
# 读取数据(不删除列表中的数据)
lrange key start end

python中的切片是左闭右开区间 test[0:3]读取的列表中的第0,1,2共3个值

操作集合

# 添加数据
sadd key value1 value2 value3
# 读取数据并从集合中删除 count 读取多少个值
spop key count 
# 查看集合中有多少值
scard key

python中使用redis

import redis
client = redis.StrictRedis()


# 列表左侧添加
client.lpush('chapter_6', 123)
# 查看长度
list_len = client.llen('chapter_6')
print(list_len)
# 左侧读取并删除
client.lpop('chapter_6')
# 集合添加
client.sadd("test_set", "https://www.baidu.com")
# 集合读取并删除
client.spop("url")
# 读取长度
set_length = client.scard("url")
print(set_length)

优化操作

  • 少读少写少更新
    • 批量插入,将值组合到一个列表中再插入
    • 一次性将数据读入内存
    • 如果要逐条更新,不如删除原来的数据,再重新批量插入
  • 能用Redis就不用MongoDB
    • 拒绝频繁去数据库查询

实验:抓取小说白夜行的正文内容

要求:

  • 抓取网址,并存到redis中名为url_queue的列表中
  • 获取具体内容,并将内容保存到mongoDB中
  • 使用XPath或者BS4

抓取小说白夜行的正文内容