按照功能给做一个爬虫用的方法的文档,简单描述,后续根据实践进行补充。详细描述还是得看文档
- (一级标题)文档按照3个大的阶段进行组织
- (二级标题)文档按照这个阶段常用到的库进行组织
组织的有点问题,如果用来查阅的话,按功能可能会更有效一些
发送请求
urllib库
主要有4个模块
- request:构造请求头,发起请求,各种handler处理认证,代理,cookie的设置
- parse:url的一些解析,编码
- error:请求过程中出错的处理
- robotparser:robots文件的解析
方法
urllib.request.urlopen
- 作用:发起http请求
- 返回值:HTTPResponse对象
- 参数:
- url:请求的地址
- data:(可选)发送的数据(post数据),bytes类型
- timeout:设置发送超时的时间,如果超时就会抛出异常
response = urllib.request.urlopen("http://www.baidu.com")
data = bytes(urllib.parse.urlencode({
'name': 'fatw'}), encoding='utf-8')
urllib.parse.urlencode
- 将字典类型的参数转为字符串型的GET请求参数
urllib.parse.parse_qs
- 将请求的参数转为字典
urllib.parse.parse_qsl
- 转为元组组成的列表
urllib.parse.quote
- 将内容转为URL编码,好像英文不转码
urllib.parse.unquote
- URL解码
urllib.parse.urlparse
- 将url进行拆解
urllib.parse.urlunparse
- 将提供的信息拼接成url
涉及的类
-
HTTPResponse类
- 属性:msg,status
- 方法:
- read:读取网页内容
- getheaders
-
Request类
- 作用:请求体的构造
- 属性:
- url
- data:bytes类型,如果是字典类型,可以先使用urlencode进行转换
- headers:字典,也可以通过后面的add_header()进行添加
-
HTTPBasicAuthHandler
- 作用:处理需要验证的http请求
-
ProxyHandler
- 作用:处理需要进行代理的http请求
-
HTTPCookieProcessor
- 作用:可构建一个处理cookie的handler,cookie的存取也可以直接使用代码来进行
-
HTTPError
- 处理HTTP请求错误,比如认证请求失败等等
-
URLError
- HTTPError的父类,有个reason属性返回失败原因。
-
RobotFileParser
- 解析robots文件,判断哪些能被抓取,哪些不能
requests库
让处理网页验证,代理设置,get post请求没有urllib那么麻烦
方法
get
- 作用:发起get请求
- 返回一个response
- 参数:
- url
- params:get请求的参数,字典类型
- headers:字典类型
- verify:是否验证证书
- timeout:如果传入的是一个数,则代表的是连接和读取的总和,如果是一个二元元组,则一个表示连接用时,一个表示读取用时
- auth:如果使用的是HTTPBasicAuth,可以使用元组作为参数。如果是其他的认证类型,则可以传入对应的类,比如OAuth认证(需要额外装库)
- proxies:设置代理,参数类型是字典。如果代理需要身份认证,可以使用http://user:password@host:
port这样的语法来设置代理。requests也支持socks协议的代理
post
- 参数:
- files:字典类型,post上传的文件内容。字典的值为open函数
类
response类
- 属性:
- status_code:返回的状态码
- cookie:可以使用item转为由元组组成的列表
- codes.ok:内置的http状态码
- content:内容的bytes形式
- text:内容的文本形式,如果是json格式的字符串的话,可以直接转为json进行进一步分析
Session类
- 作用:为了维持会话,因为每一次get,post方法请求相当于打开一个浏览器,也就是说两次请求之间并不是在同一个会话中。而为了避免通过设置cookie来保证身份的统一性,有了session
- 方法:
- get
- post
httpx库,支持http2.0的网站的爬取
但是httpx默认使用的是http1.1,需要申明才会使用http2.0
Client对象:
client = httpx.Client(http2=True)
官方推荐的使用方式为:
import httpx
with httpx.Client as client:
response = client.get(url)
print(response)
初始化Client对象的时候还可以指定headers
aiohttp库,支持异步请求
既提供了服务端(可以用来搭建服务器)也提供了客户端
tips:
对于那些需要调用close方法的东西都可以使用with as结构。在异步函数中在with as结构前面加上一个async可以声明一个支持异步的上下文管理器
客户端使用方式:
async def fetch(session, url):
async with session.get(url) as response:
return await response.text(), response.status
async def main():
async with aiohttp.ClientSession() as session:
html, status = await fetch(session, 'https://cuiqingcai.com')
print(f'html: {
html[:100]}...')
print(f'status: {
status}')
通过ClientSession获得一个session之后,就可以使用session来调用各种请求方法。
url参数的设置
在get方法中设置参数param,参数的类型为字典类型
在post方法中,根据不同的数据类型将数据放在不同post方法的参数后,类型同样为字典类型。
获取响应的时候
如果返回的是coroutine对象则在前面加上一个await。
超时设置
借助ClientTimeout对象,在得到Session的时候传入ClientTimeout对象
import aiohttp
import asyncio
async def main():
timeout = aiohttp.ClientTimeout(total=1)
async with aiohttp.ClientSession(timeout=timeout) as session:
async with session.get('https://httpbin.org/get') as response:
print('status:', response.status)
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
并发限制
避免同时的请求量太大,给网站爬没了。可以借助于 asyncio 的 Semaphore(信号量) 来控制并发量
信号量的使用方式:
import asyncio
import aiohttp
CONCURRENCY = 5
URL = 'https://www.baidu.com'
semaphore = asyncio.Semaphore(CONCURRENCY)
session = None
async def scrape_api():
async with semaphore:
print('scraping', URL)
async with session.get(URL) as response:
await asyncio.sleep(1)
return await response.text()
async def main():
global session
session = aiohttp.ClientSession()
scrape_index_tasks = [asyncio.ensure_future(scrape_api()) for _ in range(10000)]
await asyncio.gather(*scrape_index_tasks)
# gather函数可能有很多个参数,但是只传递了一个形参。*表示会将scrape_index_tasks依次分配给函数中的参数
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
就是将信号量加在需要控制并行量的地方。也就是get函数那。使用with结构。
网页数据解析提取
XPath库
感觉这东西比正则表达式好不到哪去
方法
etree.HTML(text)
- 作用:将text解析为html(有自动修复的功能)
etree.parse(path, etree.HTMLParser())
- 作用:将path路径下的文件解析为html
类:
lxml.etree._Element类
- 方法:
- xpath(pattern)按照pattern中的规则找节点,返回值依据pattern的模式而定,pattern一般是以//开头
XPath常用的规则
表达式 | 描述 |
---|---|
nodename | 选取此节点所有的子节点 |
/ | 从当前节点选取直接子节点 |
// | 从当前节点选取子孙节点 |
. | 选取此当前节点 |
… | 选取当前节点的父节点 |
@ | 选取属性 |
举例:
- //li/a:代表选取li节点下的直接子节点a
- //ul//a:选取li节点下的所有的子节点a
- //a[@href=“link4.html”]/…/@class:选取href属性为link4.html的a节点,然后获取其父节点,在获取其class属性
- //li[@class=“item-0”]//text():class属性为item-0的li节点下的所有子节点的文本(就是两个<>
中间包含的那部分文字,如果里面有子节点,子节点内的内容不会作为当前节点的文本返回)- //li[contains(@class, “li”)]/a/text():如果li的class属性包含li和li-first两个属性,可以使用contains来匹配,表示只要有其中一个属性就能够满足了
- //li[contains(@class, “li”) and @name=“item”]/a/text():匹配节点的两个属性
- //li[position()< 3]/a/text():按照次序选取节点
- //li[1]/ancestor:: *:第一个li节点所有的祖先节点
- //li[1]/attribute:: *:返回其所有的属性值
- child::直接子节点
- descendant::*所有子孙节点
- following::*后面所有的节点
- following-sibling::*后面所有的同级节点
上面例子中的括号里面支持运算符,表格如下:(|的那个还不会用)
运算符 | 描述 |
---|---|
or | |
and | |
mod | |
| | 计算两个节点集 //book|//cd返回所有拥有book和cd元素的节点集 |
+ | |
- | |
* | |
div | |
= | |
!= | |
> | |
> = | |
< | |
<= |
BeautifulSoup库
方法:
BeautifulSoup(html, ‘lxml’)
- 作用:将html中的文本解析为html形式
类
bs4.BeautifulSoup类:
- 属性:
- 接上节点的名称比如:soup.p得到的就是一个bs4.element.Tag类
- 方法:
- prettify():将soup中的文档以标准的缩进形式的字符串返回
- find_all(name, attrs, recursive, text, **kwargs):找到满足传入参数的节点。
- name:节点名称
- attrs:字典类型,节点的属性
- text:正则表达式类型,匹配节点的文本
- find():返回符合条件的第一个节点
- 还有其他类似的函数,只不过范围不同:
- find_parent(),find_parents()
- find_all_next(),find_next()
- find_next_sibling(),find_next_siblings()
- find_all_previous(),find_previous()
- find_previous_sibling(),find_previous_siblings()
- select():参数是css选择器表达式
bs4.element.Tag类:
- 属性:
- 可以进一步接上节点名称,得到其包含的子节点对应的类对象
- name:节点的名称
- attrs:节点的属性(是一个字典类型)
- string:获取节点元素包含的文本内容
- contents:以列表的形式返回直接子节点(可能还会含有文本)
- children:以生成器的形式返回直接子节点
- descendants:以生成器的形式返回所有子孙节点
- parent:直接父节点
- parents:以生成器的形式返回所有的父节点
- next_sibling:下一个兄弟节点
- next_siblings:生成器形式
- previous_sibling:上一个兄弟节点
- previous_siblings:生成器形式
- 方法:
- find_all:同BeautifulSoup中介绍的find_all方法
- select:同BeautifulSoup中介绍的select方法
pyquery
方法
PyQuery(html)
- 作用:
- 返回pyquery对象,其中html可以是字符串,url,文件名
类
pyquery类:
- 方法:
__call__
():通过对象名()的方式进行调用,传入的参数为css选择器,返回的还有pyquery对象- find:在所有的子类中进行筛选
- children:在直接子类中进行筛选
- parent:直接父节点
- parents:所有父节点,这个里面还可以传入CSS选择器进行筛选
- sblings:兄弟节点
- items:选择器选中之后不管是多少个都是返回pyquery对象,如果有多个对象的话就可以使用items返回一个生成器来获取到每一个选中的节点
- attrs:传入属性名可以获得属性值,当这个pyquery对象包含的是多个节点的时候,返回的是第一个节点对应的属性。已修改的方式(传递键值对)传入参数
- text:返回的是节点内的纯文本,不管是不是直属于这个节点的还是直属于他子节点的,都会返回。传入参数表示进行修改
- html():返回html文本,如果对象包含多个节点,同样需要遍历获取。传入参数表示进行修改
- addClass:给选中的节点增加属性
- removeClass:移除选中节点的属性
- remove:移除节点。整个就不存在了
parsel
方法
Selector(text)
- 作用:
- 返回Selector对象
类
Selector类
- 方法:
- xpath:传入XPath表达式,返回的结果是SelectorList类,即便里面是文本内容
- css:传入CSS选择器,返回的结果是SelectorList类
- re:把Selector中的内容按照文本的形式匹配到正则表达式上,返回匹配的部分或者括号内的部分
- re_first:只返回第一个符合规则的结果
SelectorList类
- 方法:
- get:返回SelectorList中第一个Selector的内容文本
- getall:所有,以列表的形式返回
数据的存储
txt文件存储
python文件读写
json文件存储
json库
- loads(): 字符串转为json对象,参数是字符串
- load(): 将一个文件操作对象作为参数传入函数中,功能与上述类似
- dumps(): json对象转为字符串
- json变量
- indent:控制json以多少个字符的形式进行缩进
- ensure_ascii:为False的时候可以存储中文
- dump:与上述dump类似,不过多了一个文件操作对象
- get(): 如果参数只有键,表示读取。如果还有值则表示惊醒修改。
json中的字符串需要使用双引号进行包裹
CSV文件存储
csv库
csv每一行以逗号或者制表符进行分隔,每一行代表一条记录。是纯文本,与含有文本,格式,数值,公式的xls文件不同
方法:
- writer(): 初始化写入对象
- 文件操作对象
- delimiter:列与列之间的分隔符
- DictWriter(): 初始化写入对象
- 文件操作对象
- fieldnames:传入的是后续写入数据中字典的键
- Reader(): 返回Reader对象,后续可以使用迭代器的方式输出文件中的内容
- 文件操作对象
类
writer()返回的类
- 方法
- writerow(): 参数为想要写入的数据,列表形式
- writerows(): 参数为想要写入的数据,二维列表形式
DictWriter()返回的类
- 方法
- writerow(): 参数为想要写入的数据,字典形式,键为初始化时fieldnames中的数据
- writerows(): 参数为想要写入的数据,二维列表形式
mysql存储
pymysql库
方法
- pymysql.connect():参数为连接数据库所需要的参数,返回数据库连接对象
- db.cursor(): db为上面方法所返回的对象,该方法得到cursor对象
类
connection类:
- 方法:
- cursor():返回cursor类
- close():关闭连接
- commit(): 对于增删改的操作需要commit之后才会真正执行
- rollback(): 事务回滚
tips:在插入数据的时候如果遇到主键已经存在的数据需要更新而不是插入,可以在sql语句后面加上ON DUPLICATE KEY UPDATE
cursor类:
- 属性:
- rowcount:查询结果的条数
- 方法:
- execute():执行sql语句
- fetchone():取出一条数据,偏移向后偏移一个
- fetchall():取出偏移后面的所有数据,如果数据量比较大,建议一条一条取
这部分还是得按对数据的操作来组织整理
MongoDB存储
pymongo库
连接
client = pymongo.MongoClient(host='localhost', port=27017)
client = MongoClient('mongodb://localhost:27017/')
指定数据库
db = client.test
# db = client['test']
指定集合
集合相当于关系型数据库中的表
collection = db.students
# collection = db['students']
插入数据
mongodb数据的插入,不管数据是不是会重复,而且不要求插入数据的字段完全一致
# 单条数据的插入
student = {
'id': '20170101',
'name': 'Jordan',
'age': 20,
'gender': 'male'
}
result = collection.insert_one(student)
# 多条数据的插入
result = collection.insert_many([student1, student2])
查询
result = collection.find_one({
'name': 'Mike'})
# 根据objectid来查询
from bson.objectid import ObjectId
result = collection.find_one({
'_id': ObjectId('593278c115c2602667ec6bae')})
# 查询多条数据
results = collection.find({
'age': 22})
for result in results:
print(result)
# 更多,参数中的值,相当于是筛选条件
results = collection.find({
'age': {
'$gt': 20}})
比较符号
符号 | 含义 | 实例 |
---|---|---|
$lt | 小于 | {‘age’: {‘$lt’: 20}} |
$gt | 大于 | {‘age’: {‘$gt’: 20}} |
$lte | 小于等于 | {‘age’: {‘$lte’: 20}} |
$gte | 大于等于 | {‘age’: {‘$gte’: 20}} |
$ne | 不等于 | {‘age’: {‘$ne’: 20}} |
$in | 在范围内 | {‘age’: {‘$in’: [20, 30]}} |
$nin | 不在范围内 | {‘age’: {‘$nin’: [20, 30]}} |
功能符号
符号 | 含义 | 实例 | 实例含义 |
---|---|---|---|
$regex | 匹配正则表达式 | {‘name’: {‘$regex’: ‘^M.*’}} | name以M为开头 |
$exists | 属性是否存在 | {‘name’: {‘$exists’: True}} | 存在name属性 |
$type | 类型判断 | {‘age’: {‘$type’: ‘int’}} | age的类型为int |
$mod | 数字模操作 | {‘age’: {‘$mod’: [5, 0]}} | age模5余0 |
$text | 文本查询 | {‘KaTeX parse error: Expected '}', got 'EOF' at end of input: text': {'search’: ‘Mike’}} | text类型的属性中包含有Mike字符串 |
$where | 高级条件查询 | {‘$where’: ‘obj.fans_count == obj.follows_count’}} | 自身粉丝数等于关注数 |
排序
results = collection.find().sort('name', pymongo.ASCENDING)
偏移
# skip跳过两个,limit只取两个
results = collection.find().sort('name', pymongo.ASCENDING).skip(2)
results = collection.find().sort('name', pymongo.ASCENDING).skip(2).limit(2)
更新
# student为字典类型,更新过的数据, condition为条件
condition = {
'name': 'Mike'}
result = collection.update_one(condition, {
'$set': student})
# 更新多条数据,inc是increase
condition = {
'age': {
'$gt': 20}}
result = collection.update_many(condition, {
'$inc': {
'age': 1}})
删除
result = collection.delete_one({
'name': 'Kevin'})
# 删除多条数据
result = collection.delete_many({
'age': {
'$lt': 25}})
Redis缓存存储
redis是一个基于内存的,高效的键值型非关系数据库
连接redis
# 也可以使用connectionPool创建连接,StrictRedis在内部也是创建了一个connectionPool进行连接
redis = StrictRedis(host='localhost', port=6379, db=0, password='')
键操作
方法 | 作用 | 参数说明 | 实例 | 实例说明 | 实例结果 |
---|---|---|---|---|---|
exists(name) | 判断一个键是否存在 | name:键名 | redis.exists(‘name’) | 是否存在name这个键 | True |
delete(name) | 删除一个键 | name:键名 | redis.delete(‘name’) | 删除name这个键 | 1 |
type(name) | 判断键的类型 | name:键名 | redis.type(‘name’) | 查看name这个键的属性 | b’string |
keys(pattern) | 获取所有符合规则的键 | pattern:匹配规则 | redis.key(‘n.*’) | 匹配所有以n开头的键 | [b’name’] |
randomkey() | 随机获取一个键 | randomkey() | 随机获取一个键 | b’name’ | |
rename(src, dst) | 对键重命名 | src:原键名,dst:新键名 | redis.rename(‘name’, ‘nickname’) | 将键name改名为nickname | True |
dbsize() | 获取当前数据库中键的个数 | dbsize() | 获取当前数据库中键的个数 | 100 | |
expire(name, time) | 设置键的过期时间 | time:秒数 | redis.expire(‘name’, 2) | 将name键的过期时间设置为2秒 | True |
ttl(name) | 获取键的过期时间 | redis.ttl(‘name’) | 获取name这个键的过期时间 | 1 (1表示永不过期) | |
move(name, db) | 将键移到其他的数据库 | db:目标数据库代号 | redis.move(‘name’, 2) | 将name键移动到2号数据库 | True |
flushdb() | 删除当前数据库中所有的键 | flushdb() | 删除当前数据库中所有的键 | Ture | |
flushall() | 删除所有数据库中的所有键 | flushall() | 删除所有数据库中的所有键 | True |
字符串操作
方法 | 作用 | 参数说明 | 示例 | 示例说明 | 示例结果 |
---|---|---|---|---|---|
set(name, value) |
给数据库中键为name 的string 赋予值value |
name : 键名;value : 值 |
redis.set('name', 'Bob') |
给name 这个键的value 赋值为Bob |
True |
get(name) |
返回数据库中键为name 的string 的value |
name :键名 |
redis.get('name') |
返回name 这个键的value |
b'Bob' |
getset(name, value) |
给数据库中键为name 的string 赋予值value 并返回上次的value |
name :键名;value :新值 |
redis.getset('name', 'Mike') |
赋值name 为Mike 并得到上次的value |
b'Bob' |
mget(keys, *args) |
返回多个键对应的value |
keys :键的列表 |
redis.mget(['name', 'nickname']) |
返回name 和nickname 的value |
[b'Mike', b'Miker'] |
setnx(name, value) |
如果不存在这个键值对,则更新value ,否则不变 |
name :键名 |
redis.setnx('newname', 'James') |
如果newname 这个键不存在,则设置值为James |
第一次运行结果是True ,第二次运行结果是False |
setex(name, time, value) |
设置可以对应的值为string 类型的value ,并指定此键值对应的有效期 |
name : 键名;time : 有效期; value :值 |
redis.setex('name', 1, 'James') |
将name 这个键的值设为James ,有效期为1秒 |
True |
setrange(name, offset, value) |
设置指定键的value 值的子字符串 |
name :键名;offset :偏移量;value :值 |
redis.set('name', 'Hello') redis.setrange('name', 6, 'World') |
设置name 为Hello 字符串,并在index 为6的位置补World |
11,修改后的字符串长度 |
mset(mapping) |
批量赋值 | mapping :字典 |
redis.mset({'name1': 'Durant', 'name2': 'James'}) |
将name1 设为Durant ,name2 设为James |
True |
msetnx(mapping) |
键均不存在时才批量赋值 | mapping :字典 |
redis.msetnx({'name3': 'Smith', 'name4': 'Curry'}) |
在name3 和name4 均不存在的情况下才设置二者值 |
True |
incr(name, amount=1) |
键为name 的value 增值操作,默认为1,键不存在则被创建并设为amount |
name :键名;amount :增长的值 |
redis.incr('age', 1) |
age 对应的值增1,若不存在,则会创建并设置为1 |
1,即修改后的值 |
decr(name, amount=1) |
键为name 的value 减值操作,默认为1,键不存在则被创建并将value 设置为-amount |
name :键名; amount :减少的值 |
redis.decr('age', 1) |
age 对应的值减1,若不存在,则会创建并设置为-1 |
-1,即修改后的值 |
append(key, value) |
键为name 的string 的值附加value |
key :键名 |
redis.append('nickname', 'OK') |
向键为nickname 的值后追加OK |
13,即修改后的字符串长度 |
substr(name, start, end=-1) |
返回键为name 的string 的子串 |
name :键名;start :起始索引;end :终止索引,默认为-1,表示截取到末尾 |
redis.substr('name', 1, 4) |
返回键为name 的值的字符串,截取索引为1~4的字符 |
b'ello' |
getrange(key, start, end) |
获取键的value 值从start 到end 的子字符串 |
key :键名;start :起始索引;end :终止索引 |
redis.getrange('name', 1, 4) |
返回键为name 的值的字符串,截取索引为1~4的字符 |
b'ello' |
列表操作
方法 | 作用 | 参数说明 | 示例 | 示例说明 | 示例结果 |
---|---|---|---|---|---|
rpush(name, *values) |
在键为name 的列表末尾添加值为value 的元素,可以传多个 |
name :键名;values :值 |
redis.rpush('list', 1, 2, 3) |
向键为list 的列表尾添加1、2、3 |
3,列表大小 |
lpush(name, *values) |
在键为name 的列表头添加值为value 的元素,可以传多个 |
name :键名;values :值 |
redis.lpush('list', 0) |
向键为list 的列表头部添加0 |
4,列表大小 |
llen(name) |
返回键为name 的列表的长度 |
name :键名 |
redis.llen('list') |
返回键为list 的列表的长度 |
4 |
lrange(name, start, end) |
返回键为name 的列表中start 至end 之间的元素 |
name :键名;start :起始索引;end :终止索引 |
redis.lrange('list', 1, 3) |
返回起始索引为1终止索引为3的索引范围对应的列表 | [b'3', b'2', b'1'] |
ltrim(name, start, end) |
截取键为name 的列表,保留索引为start 到end 的内容 |
name :键名;start :起始索引;end :终止索引 |
ltrim('list', 1, 3) |
保留键为list 的索引为1到3的元素 |
True |
lindex(name, index) |
返回键为name 的列表中index 位置的元素 |
name :键名;index :索引 |
redis.lindex('list', 1) |
返回键为list 的列表索引为1的元素 |
b’2′ |
lset(name, index, value) |
给键为name 的列表中index 位置的元素赋值,越界则报错 |
name :键名;index :索引位置;value :值 |
redis.lset('list', 1, 5) |
将键为list 的列表中索引为1的位置赋值为5 |
True |
lrem(name, count, value) |
删除count 个键的列表中值为value 的元素 |
name :键名;count :删除个数;value :值 |
redis.lrem('list', 2, 3) |
将键为list 的列表删除两个3 |
1,即删除的个数 |
lpop(name) |
返回并删除键为name 的列表中的首元素 |
name :键名 |
redis.lpop('list') |
返回并删除名为list 的列表中的第一个元素 |
b'5' |
rpop(name) |
返回并删除键为name 的列表中的尾元素 |
name :键名 |
redis.rpop('list') |
返回并删除名为list 的列表中的最后一个元素 |
b'2' |
blpop(keys, timeout=0) |
返回并删除名称在keys 中的list 中的首个元素,如果列表为空,则会一直阻塞等待 |
keys :键列表;timeout : 超时等待时间,0为一直等待 |
redis.blpop('list') |
返回并删除键为list 的列表中的第一个元素 |
[b'5'] |
brpop(keys, timeout=0) |
返回并删除键为name 的列表中的尾元素,如果list 为空,则会一直阻塞等待 |
keys :键列表;timeout :超时等待时间,0为一直等待 |
redis.brpop('list') |
返回并删除名为list 的列表中的最后一个元素 |
[b'2'] |
rpoplpush(src, dst) |
返回并删除名称为src 的列表的尾元素,并将该元素添加到名称为dst 的列表头部 |
src :源列表的键;dst :目标列表的key |
redis.rpoplpush('list', 'list2') |
将键为list 的列表尾元素删除并将其添加到键为list2 的列表头部,然后返回 |
b'2' |
集合操作
方法 | 作用 | 参数说明 | 示例 | 示例说明 | 示例结果 |
---|---|---|---|---|---|
sadd(name, *values) |
向键为name 的集合中添加元素 |
name :键名;values :值,可为多个 |
redis.sadd('tags', 'Book', 'Tea', 'Coffee') |
向键为tags 的集合中添加Book 、Tea 和Coffee 这3个内容 |
3,即插入的数据个数 |
srem(name, *values) |
从键为name 的集合中删除元素 |
name :键名;values :值,可为多个 |
redis.srem('tags', 'Book') |
从键为tags 的集合中删除Book |
1,即删除的数据个数 |
spop(name) |
随机返回并删除键为name 的集合中的一个元素 |
name :键名 |
redis.spop('tags') |
从键为tags 的集合中随机删除并返回该元素 |
b'Tea' |
smove(src, dst, value) |
从src 对应的集合中移除元素并将其添加到dst 对应的集合中 |
src :源集合;dst :目标集合;value :元素值 |
redis.smove('tags', 'tags2', 'Coffee') |
从键为tags 的集合中删除元素Coffee 并将其添加到键为tags2 的集合 |
True |
scard(name) |
返回键为name 的集合的元素个数 |
name :键名 |
redis.scard('tags') |
获取键为tags 的集合中的元素个数 |
3 |
sismember(name, value) |
测试member 是否是键为name 的集合的元素 |
name :键值 |
redis.sismember('tags', 'Book') |
判断Book 是否是键为tags 的集合元素 |
True |
sinter(keys, *args) |
返回所有给定键的集合的交集 | keys :键列表 |
redis.sinter(['tags', 'tags2']) |
返回键为tags 的集合和键为tags2 的集合的交集 |
{b'Coffee'} |
sinterstore(dest, keys, *args) |
求交集并将交集保存到dest 的集合 |
dest :结果集合;keys :键列表 |
redis.sinterstore('inttag', ['tags', 'tags2']) |
求键为tags 的集合和键为tags2 的集合的交集并将其保存为inttag |
1 |
sunion(keys, *args) |
返回所有给定键的集合的并集 | keys :键列表 |
redis.sunion(['tags', 'tags2']) |
返回键为tags 的集合和键为tags2 的集合的并集 |
{b'Coffee', b'Book', b'Pen'} |
sunionstore(dest, keys, *args) |
求并集并将并集保存到dest 的集合 |
dest :结果集合;keys :键列表 |
redis.sunionstore('inttag', ['tags', 'tags2']) |
求键为tags 的集合和键为tags2 的集合的并集并将其保存为inttag |
3 |
sdiff(keys, *args) |
返回所有给定键的集合的差集 | keys :键列表 |
redis.sdiff(['tags', 'tags2']) |
返回键为tags 的集合和键为tags2 的集合的差集 |
{b'Book', b'Pen'} |
sdiffstore(dest, keys, *args) |
求差集并将差集保存到dest 集合 |
dest :结果集合;keys :键列表 |
redis.sdiffstore('inttag', ['tags', 'tags2']) |
求键为tags的集合和键为 tags2的集合的差集并将其保存为 inttag` |
3 |
smembers(name) |
返回键为name 的集合的所有元素 |
name :键名 |
redis.smembers('tags') |
返回键为tags 的集合的所有元素 |
{b'Pen', b'Book', b'Coffee'} |
srandmember(name) |
随机返回键为name 的集合中的一个元素,但不删除元素 |
name :键值 |
redis.srandmember('tags') |
随机返回键为tags 的集合中的一个元素 |
有序集合操作
方法 | 作用 | 参数说明 | 示例 | 示例说明 | 示例结果 |
---|---|---|---|---|---|
zadd(name, *args, **kwargs) |
向键为name 的zset中添加元素member,score用于排序。如果该元素存在,则更新其顺序 |
name : 键名;args :可变参数 |
redis.zadd('grade', 100, 'Bob', 98, 'Mike') |
向键为grade 的zset中添加Bob (其score 为100),并添加Mike (其score 为98) |
2,即添加的元素个数 |
zrem(name, *values) |
删除键为name 的zset中的元素 |
name :键名;values :元素 |
redis.zrem('grade', 'Mike') |
从键为grade 的zset中删除Mike |
1,即删除的元素个数 |
zincrby(name, value, amount=1) |
如果在键为name 的zset中已经存在元素value ,则将该元素的score 增加amount ;否则向该集合中添加该元素,其score 的值为amount |
name :key名;value :元素;amount :增长的score 值 |
redis.zincrby('grade', 'Bob', -2) |
键为grade 的zset中Bob 的score 减2 |
98.0,即修改后的值 |
zrank(name, value) |
返回键为name 的zset中元素的排名,按score 从小到大排序,即名次 |
name :键名;value :元素值 |
redis.zrank('grade', 'Amy') |
得到键为grade 的zset中Amy 的排名 |
1 |
zrevrank(name, value) |
返回键为name 的zset中元素的倒数排名(按score 从大到小排序),即名次 |
name :键名;value :元素值 |
redis.zrevrank('grade', 'Amy') |
得到键为grade 的zset中Amy 的倒数排名 |
2 |
zrevrange(name, start, end, withscores=False) |
返回键为name 的zset(按score 从大到小排序)中index 从start 到end 的所有元素 |
name :键值;start :开始索引;end :结束索引;withscores :是否带score |
redis.zrevrange('grade', 0, 3) |
返回键为grade 的zset中前四名元素 |
[b'Bob', b'Mike', b'Amy', b'James'] |
zrangebyscore(name, min, max, start=None, num=None, withscores=False) |
返回键为name 的zset中score 在给定区间的元素 |
name :键名;min :最低score ;max :最高score ; start :起始索引;num :个数;withscores :是否带score |
redis.zrangebyscore('grade', 80, 95) |
返回键为grade 的zset中score 在80和95之间的元素 |
[b'Bob', b'Mike', b'Amy', b'James'] |
zcount(name, min, max) |
返回键为name 的zset中score 在给定区间的数量 |
name :键名;min :最低score ;max:最高score |
redis.zcount('grade', 80, 95) |
返回键为grade 的zset中score 在80到95的元素个数 |
2 |
zcard(name) |
返回键为name 的zset的元素个数 |
name :键名 |
redis.zcard('grade') |
获取键为grade 的zset中元素的个数 |
3 |
zremrangebyrank(name, min, max) |
删除键为name 的zset中排名在给定区间的元素 |
name :键名;min :最低位次;max :最高位次 |
redis.zremrangebyrank('grade', 0, 0) |
删除键为grade 的zset中排名第一的元素 |
1,即删除的元素个数 |
zremrangebyscore(name, min, max) |
删除键为name 的zset中score 在给定区间的元素 |
name :键名;min :最低score ;max :最高score |
redis.zremrangebyscore('grade', 80, 90) |
删除score 在80到90之间的元素 |
1,即删除的元素个数 |
散列操作
方法 | 作用 | 参数说明 | 示例 | 示例说明 | 示例结果 |
---|---|---|---|---|---|
hset(name, key, value) |
向键为name 的散列表中添加映射 |
name :键名;key :映射键名;value :映射键值 |
hset('price', 'cake', 5) |
向键为price 的散列表中添加映射关系,cake 的值为5 |
1,即添加的映射个数 |
hsetnx(name, key, value) |
如果映射键名不存在,则向键为name 的散列表中添加映射 |
name :键名;key :映射键名;value :映射键值 |
hsetnx('price', 'book', 6) |
向键为price 的散列表中添加映射关系,book 的值为6 |
1,即添加的映射个数 |
hget(name, key) |
返回键为name 的散列表中key 对应的值 |
name :键名;key :映射键名 |
redis.hget('price', 'cake') |
获取键为price 的散列表中键名为cake 的值 |
5 |
hmget(name, keys, *args) |
返回键为name 的散列表中各个键对应的值 |
name :键名;keys :映射键名列表 |
redis.hmget('price', ['apple', 'orange']) |
获取键为price 的散列表中apple 和orange 的值 |
[b'3', b'7'] |
hmset(name, mapping) |
向键为name 的散列表中批量添加映射 |
name :键名;mapping :映射字典 |
redis.hmset('price', {'banana': 2, 'pear': 6}) |
向键为price 的散列表中批量添加映射 |
True |
hincrby(name, key, amount=1) |
将键为name 的散列表中映射的值增加amount |
name :键名;key :映射键名;amount :增长量 |
redis.hincrby('price', 'apple', 3) |
key 为price 的散列表中apple 的值增加3 |
6,修改后的值 |
hexists(name, key) |
键为name 的散列表中是否存在键名为键的映射 |
name :键名;key :映射键名 |
redis.hexists('price', 'banana') |
键为price 的散列表中banana 的值是否存在 |
True |
hdel(name, *keys) |
在键为name 的散列表中,删除键名为键的映射 |
name :键名;keys :映射键名 |
redis.hdel('price', 'banana') |
从键为price 的散列表中删除键名为banana 的映射 |
True |
hlen(name) |
从键为name 的散列表中获取映射个数 |
name : 键名 |
redis.hlen('price') |
从键为price 的散列表中获取映射个数 |
6 |
hkeys(name) |
从键为name 的散列表中获取所有映射键名 |
name :键名 |
redis.hkeys('price') |
从键为price 的散列表中获取所有映射键名 |
[b'cake', b'book', b'banana', b'pear'] |
hvals(name) |
从键为name 的散列表中获取所有映射键值 |
name :键名 |
redis.hvals('price') |
从键为price 的散列表中获取所有映射键值 |
[b'5', b'6', b'2', b'6'] |
hgetall(name) |
从键为name 的散列表中获取所有映射键值对 |
name :键名 |
redis.hgetall('price') |
从键为price 的散列表中获取所有映射键值对 |
{b'cake': b'5', b'book': b'6', b'orange': b'7', b'pear': b'6'} |
Elasticsearch搜索引擎存储
版本是7.16.3(用到之后再补充,对elasticsearch的机制还有没足够的了解)
数据存到这里面便于搜索分析
- 一个分布式的实时文档存储库,每个字段都可以被索引与搜索
- 一个分布式的实时分析搜索引擎
- 能胜任上百个服务节点的扩展,支持PB级别的结构化或者非结构化数据
连接
es = Elasticsearch(['https://localhost:9200'], verify_certs=True)
创建索引
result = es.indices.create(index='news', ignore=400)
# ignore表示的是忽略400这个错误(表示索引已存在)
删除索引
更新数据
删除数据
查询数据
RabbitMQ的使用
主要应用于数据消息的通信,进程间的通信机制。是一个消息队列。