【20天搞定Python爬虫】第八天:redis在爬虫中的应用
千锋python
2021年05月19日 17:45
收录于文集
共23篇

【千锋教育干货暴击】

如果你想更好的学习python乃至转行,弯道超车,快人一步!本课程零基础即可加入学习,抓住大数据、机器学习、人工智能时代的红利,开启你的第一行代码吧!

↓    ↓    ↓

千锋教育Python教程_700集零基础Python入门到精通教程(保姆级新手教程)​

千锋教育Python教程全套_python零基础入门到精通(学完可达到Python工程师水平)​

cut-off

本文章的主要内容如下:

  • Redis简介

  • Redis适用场景

  • Redis的安装

  • Redis数据类型与操作

  • 在Python中操作Redis

——————————————

目前,大型的爬虫系统采用的都是分布式爬取结构,即分布式爬虫。在分布式爬虫中,将爬取任务分配给多台计算机同时处理,相当于将多个单机联系起来形成一个整体来完成任务,这样可提高爬虫的可用性及稳定性。在分布式爬虫中通过消息队列将各个单机联系起来,而最常被用作消息队列的就是Redis。

Redis简介

Redis是一种基于键值对(key-value)的NoSQL数据库,与很多键值对数据库不同的是,Redis中的值由string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、HyperLogLog、GEO(地理信息定位)等多种数据结构和算法组成,因此Redis可以满足很多的应用场景,而且因为Redis会将所有数据都存放在内存中,所以读写性能非常好。

不仅如此,Redis还可以将内存的数据利用快照和日志的形式保存到硬盘上,这样在发生类似断电或者故障的时候,内存中的数据不会“丢失”。

除了上述功能以外,Redis还提供了键过期、发布订阅、事务、流水线、Lua脚本等附加功能。

官方网站(英文)https://redis.io

中文网站:http://www.redis.cn

Redis适用场景

众多语言都支持Redis,因为Redis交换数据快,在服务器中常用来存储一些需要频繁调取的数据,节省内存开销,也极大的提升了速度。将一些热点数据存储到Redis中,要用的时候,直接从内存取,极大的提高了速度和节约了服务器的开销。

1.消息队列

消息队列系统是一个大型网站的必备基础组件,因为其具有业务解耦、非实时业务削峰等特性。Redis提供了发布订阅功能和阻塞队列的功能。

2.社交功能

点赞、关注、好友、推送、下拉刷新等是社交网站的必备功能,社交网站的访问量通常比较大,而且传统的关系型数据不太适合保存这种类型的数据,Redis提供的数据结构可以相对容易地实现这些功能。

3.计数器

网站中的计数功能作用至关重要,例如视频网站的播放次数、电商网站的浏览数,为了保证数据的实时性,每一次播放和浏览都要做加1的动作,如果并发量很大对于传统关系型数据库的性能来说是种压力。Redis则天然支持计数功能。

4.排行榜功能

排行榜系统几乎存在所有的网站,例如热度排名、按照时间发布的排行,按照复杂维度计算出的排行榜。Redis提供了列表和有序集合数据结构,合理地使用这些数据结构可以很方便地构建出各种排行榜系统。

5.缓存

缓存机制几乎在所有的大型网站都有使用,合理地使用缓存不仅可以加快数据的访问速度,而且能够有效地降低后端数据源的压力。Redis提供了键值过期时间设置,并且提供了灵活控制最大内存和内存溢出后的淘汰策略。

6.分布式和持久化

Redis 3.0版本以后官方加入了分布式的支持,主要是两个方面:

  • Redis服务器主从热备,确保系统稳定性

  • Redis分片应对海量数据和高并发

当然Redis还有很多适用的场景,每个技术都有属于自己的应用场景,只有对技术的特点有一定清晰的认识,才能更好的利用技术,发挥其最大的优势。大家加油哦!

Redis的安装

在Windows下安装Redis过程较简单,首先下载后缀名为.zip的Redis压缩包(https://github.com/tporadowski/redis/releases),如图所示。

将下载的压缩文件解压到一个固定的目录,使用DOS命令窗口进入该解压目录,该目录下主要文件介绍:

redis跟其他数据库一样,也需要启动服务器,命令(redis-server.exe redis.windows.conf)如下:

该命令中的redis.windows.conf是Redis中的配置文件。将Redis添加到服务中命令如下:

运行该命令之后,就可以通过net start redis 启动服务器或者通过net stop redis关闭服务器了。命令如图:

至此Redis在Windows下已经安装成功!

如果要进入交互模式,则在终端页面输入:redis-cli,成功连接到Redis后即可操作Redis中的数据类型。

如果是mac系统可以按照如下步骤操作完成:

step1: 使用brew 进行下载安装:brew install redis;

step2: 安装完成之后,执行redis-server

step3: 如果要使用终端的交互模式,在终端输入:redis-cli即可

Redis数据类型与操作

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。

  • redis常用命令请参考:http://redis.cn/commands.html

注意以下命令均是在redis-cli的交互式下进行的。

string

String是最简单的类型,你可以理解为一个key 对应一个value。string 类型是二进制安全的。意思是redis 的string 可以包含任何数据,比如jpg 图片或者序列化的对象。string类型是Redis最基本的数据类型,一个键最大能存储512MB。

应用场景:比如一些微博数,粉丝数等常规计数。

设置键

代码块
JavaScript
自动换行
复制代码
命令:SET key value  #设置单键值对
>set h1 100  #设置h1的值为100

命令:mset key  value [key  value] #设置多个键值对
>mset name '王宝强' age 30 gender '男'

命令:setex   key seconds  value #设置键值及过期时间(秒单位)
>setex  age 100 20 #设置年龄的值为20,过期时间100秒
复制成功

获取键

代码块
JavaScript
自动换行
复制代码
命令:get  key  #获取单个键
>get h1

命令:mget key1 key2  key3  #获取多个键
>mget name age sex
复制成功

查看过期时间

代码块
JavaScript
自动换行
复制代码
命令:ttl key
>ttl a1 #查看a1的过期时间
复制成功

运算

代码块
JavaScript
自动换行
复制代码
原来的值必须是数值字符串
命令:incr key  #将对应的key 加1 
命令:decr key  #将对应的key值减1
命令:incrby  key  num   #将对应的key加指定值
命令:decrby  key  num   #将对应的key的值减去指定值
复制成功

其它操作

代码块
JavaScript
自动换行
复制代码
命令:append key  value  #追加值,redis中值都是字符串,追加就是字符拼接
>append name 'hello'  #如果原来的值是tom,那么现在就是tomhello

命令:strlen  key  #获取值得长度
复制成功

hash

Redis hash 是一个键值(key=>value)对集合。Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。每个 hash 可以存储 2的32次方 -1 键值对(40多亿)。存储形式:key = {name:'tom&#​39;,age: 18}

应用场景:存储部分变更的数据,如用户信息等。

设置值

代码块
JavaScript
自动换行
复制代码
命令:hset  key  field   value  #设置key所指对象的指定属性的值
命令:hmset key  field   value  [field value] #设置key所指对象的多个属性值
命令:hsetnx  key  field  value  #当field字段不存在时 设置key所指对象的field属性值

hset person name '二狗子'
hmset person age 20 sex '男'
hsetnx person maried '未婚'
复制成功

获取值

代码块
JavaScript
自动换行
复制代码
命令:hget key field  #获取key指定的对象的属性值
命令:hmget  key  field [field]  #获取key指定对象的多个属性值
命令:hgetall key   #获取key所指对象的所有属性的名称和值
命令:hkeys   key   #获取key所指对象的所有属性名
命令:hvals   key   #获取key所指对象是的所有属性值
命令:hlen key      #获取key所指对象的属性个数
复制成功

其它操作

代码块
JavaScript
自动换行
复制代码
命令:hincrby  key   field   increment  #为key所指对象的指定字段的整数值加上increment
命令:hincrbyfloat  key  field  increment #为key所指对象的指定字段的实数值加上increment
命令:hexists key  field  #判断当前的字段是否存在在(在返回1 否则返回0)
命令:hdel  key  field  [field] #删除字段和值
复制成功

list

redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。列表最多可存储 2的32次方 - 1 元素 (4294967295, 每个列表可存储40多亿)。

常应用于:1、对数据量大的集合数据删减 2、任务队列

添加数据

代码块
JavaScript
自动换行
复制代码
命令:lpush  key   value [value]    #头部插入数据
命令:lpushx  key  value            #如果列表存在则在列表头部插入数据
命令:rpush  key  value  [value]    #在列表尾部添加数据
命令:rpushx  key  value            #如果列表存在,则在尾部添加数据
命令:linsert key  before|after  value  value  #在指定值前或后插入数据
命令:lset  key  index  value       #设定指定索引元素的值
注意:索引的值从左边开始,向右增加,左边第一个是0,从右边向左索引编号为:-1 -2...
复制成功

获取数据

代码块
JavaScript
自动换行
复制代码
命令:lpop  key                #左侧出队并返回出队元素
命令:rpop  key                #右侧出队并返回出队元素
命令:lindex key    index    #返回指定索引的值
命令:lrange  key  start  end  #返回存储列表中的指定范围的元素
                               [start,end]
命令:lrem key count value     #从列表里移除前 count 次出现的值为 value 的元素
         count > 0: 从头往尾移除值为 value 的元素。
         count < 0: 从尾往头移除值为 value 的元素。
         count = 0: 移除所有值为 value 的元素。
复制成功

其它操作

代码块
JavaScript
自动换行
复制代码
命令:llen  key  #获取列表长度
命令:ltrim  key  start  stop  #裁剪列表 保留start到stop之间的元素,其它都删除
 ltrime  mylist  -3  -1  #从索引为-3到-2的保留, 以外的全部删除
复制成功

set 无序的集合

Redis的Set是string类型的无序集合,元素具有唯一性 不重复。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

常应用于:对两个集合间的数据进行交集、并集、差集运算。

案例:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。

添加元素

代码块
JavaScript
自动换行
复制代码
sadd  key  member [member]  #添加多个元素
复制成功

获取元素

代码块
JavaScript
自动换行
复制代码
  smembers   key   #获取集合中所有的元素
  scard    key     #返回集合元素的个数
  srandmember  key   [count]  #返回集合中随机元素的值,可以返回count个
复制成功

其它操作

代码块
JavaScript
自动换行
复制代码
spop   key [count]   #移除集合中随机的count个元素,并返回
srem  key  member1  [member2]  #移除集合中 一个或者 多个 成员
sismember  key  member   #判断元素是否在集合中  存在返回1  不在返回0
复制成功

集合操作

代码块
JavaScript
自动换行
复制代码
求多个集合的交集:  sinter  key  [key...]
求多个集合的差集 (注意比较顺序):sdiff   key  [key...]
求 多个集合的并集:   sunion  key [key....]
复制成功

zset 有序从大到小排序

Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。

常应用于:排行榜应用,取TOP N操作

添加元素

代码块
JavaScript
自动换行
复制代码
zadd  key score  member [score member]    #添加多个元素
zincrby  key  increment   member          #对指定的成员增加权重increment
复制成功

获取元素

代码块
JavaScript
自动换行
复制代码
zrange  key  start  end    #返回指定范围的元素
zcard  key                 #返回元素的个数
zcount  key min max        #返回有序集合中权重在min和max之间的元素的个数
zscore  key  member        #返回有序集合中 member(元素)  的权重(score)
zrange key  start  end  withscores  #返回当前key中 所有的权重(score)和元素(member)
复制成功

数据库切换

代码块
JavaScript
自动换行
复制代码
redis默认带有16个数据库,编号从0-15。进入redis后默认数据库是0,可以使用select num进行切换
客户端不显示中文的处理:打开客户端的时候添加参数:--raw
redis-cli --raw
复制成功

其他

代码块
JavaScript
自动换行
复制代码
keys *  #查看所有的key
keys u* #查以u开始的key
keys  n???    查找以n为开头长度为4个的key
keys  n      查找 包含 n 的所有的key

支持的正则表达式:
- h?llo   匹配第二位为任意的字符
- h*llo     匹配第二位为任意字符 0个 或多个
- h[ab]llo  匹配第二位为 a或者b的字符的key
- hello  匹配第二位除了e字符以外的任意的key
- h[a-z]llo 匹配第二位为a-z的小写字母的key

exists key #判断键是否存在
type  key   #查看key对应的value的类型
del   key   #删除指定key
expire key 10  #设置过期时间,秒
persist  key   #移除key的过期时间
rename key newkey #修改key的名称(如果新的key的名字存在 则会把存在的key的值 覆盖掉)
randomkey  #随机返回一个 key
move key  db  将键移动到指定库

flushdb  #清空当前库所有key 
flushall #清空所有库里的key

exit #退出redis客户端
quit 退出客户端

查看服务器信息
info 

dbsize 当前库中有多少key
复制成功

Python中操作Redis

redis提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。

安装redis

代码块
JavaScript
自动换行
复制代码
pip install redis
复制成功

使用python建立连接

连接redis我们使用的是redis.Redis(host,port,decode_responses),加上decode_responses=True,写入的键值对中的value为str类型,不加这个参数写入的则为字节类型。

代码块
JavaScript
自动换行
复制代码
import redis   # 导入redis模块

r = redis.Redis(host='localhost', port=6379, decode_responses=True)   # host是redis主机,需要redis服务端和客户端都启动 redis默认端口是6379
r.set('name', 'Running')  # key是"name" value是"Running" 将键值对存入redis缓存
print(r['name'])
print(r.get('name'))  # 取出键name对应的值Running
复制成功

String 字符串的操作

r.set h设置值

代码块
JavaScript
自动换行
复制代码
#在Redis中设置值,默认不存在则创建,存在则修改
r.set('name', 'zhangsan')
'''参数:
     set(name, value, ex=None, px=None, nx=False, xx=False)
     ex,过期时间(秒)
     px,过期时间(毫秒)
     nx,如果设置为True,则只有name不存在时,当前set操作才执行,同setnx(name, value)
     xx,如果设置为True,则只有name存在时,当前set操作才执行'''
复制成功

r.get 获取值

代码块
JavaScript
自动换行
复制代码
r.get('name')
复制成功

当然也存在批量的设置r.mset和获取r.mget等。

Hash 操作

redis中的Hash 在内存中类似于一个name对应一个dic来存储

hset

name对应的hash中设置一个键值对(不存在,则创建,否则,修改)

代码块
JavaScript
自动换行
复制代码
#name对应的hash中设置一个键值对(不存在,则创建,否则,修改)
r.hset(name, key, value)
r.hset("dic_name","a1","aa")
复制成功

hget

在name对应的hash中根据key获取value

代码块
JavaScript
自动换行
复制代码
r.hset("dic_name","a1","aa")
#在name对应的hash中根据key获取value
hget(name,key) 

print(r.hget("dic_name","a1"))#输出:aa
复制成功

List 操作

redis中的List在内存中按照一个name对应一个List来存储

lpush

在name对应的list中添加元素,每个新的元素都添加到列表的最左边

代码块
JavaScript
自动换行
复制代码
# 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
lpush(name,values)

r.lpush("list_name",2)
r.lpush("list_name",3,4,5)#保存在列表中的顺序为5,4,3,2
复制成功

rpush

同lpush,但每个新的元素都添加到列表的最右边

代码块
JavaScript
自动换行
复制代码
#同lpush,但每个新的元素都添加到列表的最右边
rpush(name,values)
复制成功

Set 操作

Set集合就是不允许重复的列表

sadd(name,values)

给name对应的集合中添加元素

代码块
JavaScript
自动换行
复制代码
#给name对应的集合中添加元素
r.sadd("set_name","aa")
r.sadd("set_name","aa","bb")
复制成功

smembers(name)

获取name对应的集合的所有成员

代码块
JavaScript
自动换行
复制代码
#获取name对应的集合的所有成员
复制成功

scard(name)

获取name对应的集合中的元素个数

代码块
JavaScript
自动换行
复制代码
#获取name对应的集合中的元素个数
r.scard("set_name")
复制成功

有序集合 zset

在集合的基础上,为每元素排序,元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。

zadd(name, *args, kwargs)

代码块
JavaScript
自动换行
复制代码
# 在name对应的有序集合中添加元素
r.zadd("zset_name", 6,"a1", 2, "a2", 5,"a3")
#或
r.zadd('zset_name1', b1=10, b2=5)
复制成功

zcard(name)

获取有序集合内元素的数量

代码块
JavaScript
自动换行
复制代码
#获取有序集合内元素的数量
复制成功

zcount(name, min, max)

获取有序集合中分数在[min,max]之间的个数

代码块
JavaScript
自动换行
复制代码
#获取有序集合中分数在[min,max]之间的个数
print(r.zcount("zset_name",1,5))
复制成功

由于篇幅问题只是给大家提供了部分的Python操作方法,如果大家有需要完整版的Python中操作Redis的使用方式,可以在公众号Python专栏中回复:redis 进行领取。

cut-off

需要资料也可以关注微信公众号:Python专栏,事不宜迟,一起进步吧!