NoSQL,Not Only SQL,不仅仅是SQL,泛指非关系型数据库,基于键值对的,不需要经过SQL层的解析,数据之间没有耦合性,性能高。
非关系型数据库细分如下:
爬虫数据使用非关系型数据库原因:简单高效。爬虫数据可能存在某些字段提取失败或缺失,数据可能会随时调整,且数据间可能存在嵌套关系。如果用关系型数据库,需提前建表,如果数据存在嵌套关系,需进行序列化操作后才可以存储。
1.MongoDB介绍
MongoDB将数据存储为一个文档数据结构,由键值对组成 MongoDB文档类似于json对象,字段值可以包含其他文档、数组及文档数组。
2.连接数据库
启动服务:
cd mongodb的bin文件路径----->mongod.exe --dbpath=路径
cd mongodb的bin文件路径----->mongo.exe
python中连接mongodb:
- import pymongo
- # client = pymongo.MongoClient(host='localhost',port=27017) #第一种连接
- client = pymongo.MongoClient('mongodb://localhost:27017') #第二种连接
- print(client)
3.指定数据库
如果数据库不存在则为创建
- # db = client.test #第一种指定
- db = client['test'] #第二种指定
4.指定集合
- # collection = db.user #第一种指定
- collection = db['user'] #第二种指定
5.插入数据
- data1 = {'id':'001', 'name':'aa','age':15}
- data2 = {'id':'002', 'name':'bb','age':16}
- data3 = {'id':'003', 'name':'cc','age':14}
- data4 = {'id':'004', 'name':'dd','age':14}
- collection.insert_one(data1) #插入一条数据
- collection.insert_many([data2,data3,data4]) #插入多条数据
6.数据查询
6.1 find_one()和find()查找
- # result = collection.find_one({'name':'aa'}) #返回单个结果 {'_id': ObjectId('5e1903e232a95ccef7703bda'), 'id': '001', 'name': 'aa', 'age': 15} _id为mongodb插入时自动添加的
- results = collection.find({'age':14}) #返回生成器对象
- for result in results:
- print(result)
6.2 ObjectId查找
- from bson.objectid import ObjectId
- result = collection.find_one({'_id':ObjectId('5e1903e232a95ccef7703bda')})
6.3 条件查找
- results = collection.find({'age':{'$lt':15}}) #年龄小于15
- results = collection.find({'age':{'$lte':15}}) #年龄小于等于15
- results = collection.find({'age':{'$gt':15}}) #年龄大于15
- results = collection.find({'age':{'$gte':15}}) #年龄大于等于15
- results = collection.find({'age':{'$ne':15}}) #年龄不等于15
- results = collection.find({'age':{'$in':[15,16]}}) #年龄在15-16之间,包含
- results = collection.find({'age':{'$nin':[15,16]}}) #年龄不在15-16之间
- for result in results:
- print(result)
6.4正则查找
- results = collection.find({'name':{'$regex':'^a.*'}}) #名字以a开头的正则匹配
- for result in results:
- print(result)
7.计数
- result = collection.find().count()
- result = collection.find({'age':{'$gt':14}}).count()
- print(result)
8.排序
- results = collection.find().sort('age',pymongo.ASCENDING) #默认升序
- results = collection.find().sort('age',pymongo.DESCENDING) #降序
9.偏移
- results = collection.find().sort('age').skip(2) #从第三个开始
- results = collection.find().sort('age').skip(2).limit(1) #只要第三个
10.更新
- collection.update_one({'age':15},{'$set':{'age':20}}) #update_one()修改一条,'$set"直接修改
- results = collection.update_many({'age':14},{'$inc':{'age':2}}) #update_many()修改多条,'$inc'累计修改
- print(results.matched_count,results.modified_count)
11.删除
- collection.remove({'name':'aa'})
- collection.delete_one({'name':'bb'})
- results = collection.delete_many({'age':16})
- print(results.deleted_count)
12.案例
- # 练习:爬取豆瓣电影TOP250,电影名称,评分,推荐语信息并保存到MongoDB中
- from pyquery import PyQuery as pq
- import requests
- import pymongo
-
- url = 'https://movie.douban.com/top250'
- headers = {
- 'User-Agent': 'Mozilla/5.0(Windows NT 6.1;Win64;x64)AppleWebKit/537.36(KHTML,like Gecko)Chrome/79.0.3945.88 Safari/537.36'
- }
- res = requests.get(url=url,headers=headers)
- doc = pq(res.text)
- items = doc('.info').items()
- list_all = []
- for item in items:
- movies_dict = {}
- name = pq(item.find('.hd').html()).find('span:first-child').text() #此处的find找到所有符合条件的
- score = pq(item.find('.star').html()).find('span:nth-child(2)').text()
- comment = item.find('.quote').text()
- movies_dict['name'] = name
- movies_dict['score'] = score
- movies_dict['comment'] = comment
- list_all.append(movies_dict)
-
- client = pymongo.MongoClient(host='localhost',port=27017)
- db = client.test
- collection = db.movies
- for movie in list_all:
- collection.insert_one(movie)
-
- results = collection.find()
- for result in results:
- print(result)