python爬虫11--文件存储之非关系型数据库存储MongoDB

CharlesYooSky 2020-01-11

NoSQL,Not Only SQL,不仅仅是SQL,泛指非关系型数据库,基于键值对的,不需要经过SQL层的解析,数据之间没有耦合性,性能高。

非关系型数据库细分如下:

  • 键值存储数据库:Redis、Voldemort、Oracle BDB;
  • 列表存储数据库:Cassandra、HBase、Riak;
  • 文档型数据库:CouchDB、MongoDB;
  • 图形数据库:Neo4j、InfoGrid、Infinite Graph。

爬虫数据使用非关系型数据库原因:简单高效。爬虫数据可能存在某些字段提取失败或缺失,数据可能会随时调整,且数据间可能存在嵌套关系。如果用关系型数据库,需提前建表,如果数据存在嵌套关系,需进行序列化操作后才可以存储。

1.MongoDB介绍

MongoDB将数据存储为一个文档数据结构,由键值对组成 MongoDB文档类似于json对象,字段值可以包含其他文档、数组及文档数组。

python爬虫11--文件存储之非关系型数据库存储MongoDB

 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)

 

相关推荐