1 import pymongo
2
3 #连接数据库实例(连接数据库)---》获取相应数据库---》获取相应collection集合(表)
4 client = pymongo.MongoClient(host='localhost',port=27017)
5
6 db = client.test #也可用字典形式操作,如下
7 # db = client["test"]
8
9 collection = db.students #也可用字典形式操作,如下
10 # collection = db["students"]
11
12 student1 = {
13 'id':'001',
14 'name':'haha',
15 'age':20,
16 'gender':'male'
17 }
18 student2 = {
19 'id': '002',
20 'name': 'Mike',
21 'age': 41,
22 'gender': 'male'
23 }
24 #--------------------------------------------------------------------------
25 #插入 insert into students(...) values('002',...)
26 #若不指定 _id 字段,系统默认会生成一个ObjectId
27 #可插入一条或多条数据(列表形式),python3不推荐使用insert
28 # collection.insert([student1,student2])
29 # collection.insert(student1)
30
31 #官方推荐,分开使用,返回值不是ObjectId,而是InsertOneResult对象,我们可以调用其inserted_id属性获取_id。
32 # result = collection.insert_one(student2)
33 # print(result)
34 # print(result.inserted_id)
35
36 # result = collection.insert_many([student1,student2])
37 # print(result)
38 # print(result.inserted_ids)
39
40 #------------------------------------------------------------------
41 #查询 select * from students where id=002
42 #查询条件使用字典,可使用多字段,find是多条查询
43 # result_find = collection.find({"name":"lijingbo","age":20})
44 # print(result_find.next()) #返回一个游标,游标相当于迭代器,可使用next()获取一条结果,或者使用循环遍历等,遍历结果是字典
45 #find_one:单个查询,返回字典类型
46 # result = collection.find_one({'age':20})
47 # print(result,type(result))
48 #结合关系符进行查询:$gt,$lt,$gte,$lte,$ne,$in,$nin
49 # result = collection.find({'age':{'$gt':18}})
50 # result = collection.find({'age':{'$in':[18,41]}})
51 #结合特殊符号查询:$regex
52 # result = collection.find({'name':{'$regex':'^M.*'}}) #正则
53 # result = collection.find({'name':{'$exists':True}}) #查询含有name属性的
54 # result = collection.find({'age':{'$mod':[5,0]}}) #求模,对5取余=0
55 # result = collection.find({'$where':'obj.age==20'}) #查询age为20的,obj是自身
56 # result = collection.find({'age':20}).count() #统计
57 # result = collection.find().sort('age',pymongo.ASCENDING) #按照指定字段升序排列
58 # result = collection.find().sort('age',pymongo.DESCENDING) #按照指定字段升序排列
59 # result = collection.find().sort('age',pymongo.DESCENDING).skip(2) #按照指定字段升序排列,偏移2个(就是把最前面两个跳过去了)
60 # result = collection.find().sort('age',pymongo.DESCENDING).skip(2).limit(5) #限制得到5
61 # print(result)
62 # for r in result:
63 # print(r['name'],r['age'])
64
65 #----------------------------------------------------------
66 #更新 update students set name=haha where id=001
67 #参数1:查询条件(字典);参数2:更新值(字典,键:'$set',值:字典【也可直接使用外部字典】)
68 #其他:upsert默认为False,为True时——若更新的原数据不存在,则插入数据
69 #multi——默认为False只更新查询到的第一条数据,为True时:更新全部查询到的数据
70 # $set:是mongodb内置函数,覆盖原始数据
71 # collection.update({"id":"001"},{'$set':{'age':34}},upsert=True,multi=True)
72 # print(collection.find().next())
73 #上面的官方也不推荐,可以使用下面的
74 # result = collection.update_one({'name':'haha'},{'$set':{'age':18}})
75 # result = collection.update_many({'name':'haha'},{'$set':{'age':18}})
76 # print(result) #只修改一条数据,若该数据不修改就和修改条件一样了,那有可能修改数为0
77 # print(result.matched_count,result.modified_count)
78
79
80 #-----------------------------------------------------
81 #删除,remove方法官方不推荐
82 # collection.remove({"id":"001"},justOne=1)
83 # result = collection.delete_one({'name':'Mike'})
84 # result = collection.delete_many({'name':'Mike'})
85 # print(result)
86 # print(result.deleted_count)
87
88 #---------------------------------------------------
89 #组合方法
90 # result = collection.find_one_and_delete({'name':'haha'})
91 # result = collection.find_one_and_update({'name':'haha'},{'$set':{'age':45}})
92 # result = collection.find_one_and_replace({'name':'haha'})
93 # print(result)
将数据以字典的特性存储缓存到mongodb数据库
import pickle,zlib #对象序列化 压缩数据
from datetime import datetime,timedelta #设置缓存超时间间隔
from pymongo import MongoClient
from bson.binary import Binary #MongoDB存储二进制的类型
__setitem__
使用下载的url(路由)作为key,存入系统默认的_id字段,更新数据库,若存在则更新,不存在则插入,_id唯一就可实现爬取的数据去重
用字典的形式向数据库添加一条缓存(数据)
__getitem__
__contains__
__getitem__
直接查找(self[item])clear
1 import pickle,zlib #对象序列化 压缩数据
2 from datetime import datetime,timedelta #设置缓存超时间间隔
3 from pymongo import MongoClient
4 from bson.binary import Binary #MongoDB存储二进制的类型
5 from http_ljb.tiebaspider import TiebaSpider
6 from http_ljb.qiushispider import QiushiSpider
7
8 class MongoCache:
9 def __init__(self,client=None,expires=timedelta(days=30)):
10 '''
11 初始化函数
12 :param client: 数据库连接(数据库实例)
13 :param expires: 超时时间
14 '''
15 self.client = MongoClient('localhost',27017)
16 self.db = self.client.cache #创建名为cache的数据库
17 web_page = self.db.webpage #创建集合webpage并赋值给变量
18 #创建timestamp索引,设置超时时间为30天,total_seconds会将days转为秒
19 self.db.webpage.create_index('timestamp',expireAfterSeconds=expires.total_seconds())
20
21 def __setitem__(self, key, value):
22 '''
23 用字典的形式向数据库添加一条缓存(数据)
24 :param key: 缓存的键
25 :param value: 缓存的值
26 :return:
27 '''
28 #数据---》pickle序列化---》zlib压缩---》Binary转化为mondodb需要的格式,使用格林威治时间
29 record = {'result':Binary(zlib.compress(pickle.dumps(value))),'timestamp':datetime.utcnow()}
30 #使用下载的url(路由)作为key,存入系统默认的_id字段,更新数据库,若存在则更新,不存在则插入,_id唯一就可实现爬取的数据去重
31 self.db.webpage.update({'_id':key},{'$set':record},upsert=True)
32
33 def __getitem__(self, item):
34 '''
35 将缓存数据按照item作为key取出(key仍然是下载的url)
36 :param item:键
37 :return:
38 '''
39 record = self.db.webpage.find_one({'_id':item}) #查找出来就不是Binary了,不用进行转化
40 if record:
41 return pickle.loads(zlib.decompress(record['result'])) #解压缩,反序列化
42 else:
43 raise KeyError(item + 'does not exist') #查询不到就抛出键错误异常
44
45 def __contains__(self, item):
46 '''
47 当调用in,not in ,会自动调用该方法判断链接对应网址是否在数据库中
48 :param item: 下载的url链接(路由)
49 :return:
50 '''
51 try:
52 self[item] #这一步会调用__getitem__,找不到__getitem__会抛出异常,在这里进行捕获异常只返回False,否则返回True
53 except KeyError:
54 return False
55 else:
56 return True
57
58 def clear(self):
59 '''
60 清空该集合中的数据
61 :return:
62 '''
63 self.db.webpage.drop()
调用贴吧爬取代码和百科爬取代码,使用mongodb存储爬取数据
1 import pickle,zlib #对象序列化 压缩数据
2 from datetime import datetime,timedelta #设置缓存超时间间隔
3 from pymongo import MongoClient
4 from bson.binary import Binary #MongoDB存储二进制的类型
5 from http_ljb.tiebaspider import TiebaSpider
6 from http_ljb.qiushispider import QiushiSpider
7
8 class MongoCache:
9 def __init__(self,client=None,expires=timedelta(days=30)):
10 '''
11 初始化函数
12 :param client: 数据库连接(数据库实例)
13 :param expires: 超时时间
14 '''
15 self.client = MongoClient('localhost',27017)
16 self.db = self.client.cache #创建名为cache的数据库
17 web_page = self.db.webpage #创建集合webpage并赋值给变量
18 #创建timestamp索引,设置超时时间为30天,total_seconds会将days转为秒
19 self.db.webpage.create_index('timestamp',expireAfterSeconds=expires.total_seconds())
20
21 def __setitem__(self, key, value):
22 '''
23 用字典的形式向数据库添加一条缓存(数据)
24 :param key: 缓存的键
25 :param value: 缓存的值
26 :return:
27 '''
28 #数据---》pickle序列化---》zlib压缩---》Binary转化为mondodb需要的格式,使用格林威治时间
29 record = {'result':Binary(zlib.compress(pickle.dumps(value))),'timestamp':datetime.utcnow()}
30 #使用下载的url(路由)作为key,存入系统默认的_id字段,更新数据库,若存在则更新,不存在则插入,_id唯一就可实现爬取的数据去重
31 self.db.webpage.update({'_id':key},{'$set':record},upsert=True)
32
33 def __getitem__(self, item):
34 '''
35 将缓存数据按照item作为key取出(key仍然是下载的url)
36 :param item:键
37 :return:
38 '''
39 record = self.db.webpage.find_one({'_id':item}) #查找出来就不是Binary了,不用进行转化
40 if record:
41 return pickle.loads(zlib.decompress(record['result'])) #解压缩,反序列化
42 else:
43 raise KeyError(item + 'does not exist') #查询不到就抛出键错误异常
44
45 def __contains__(self, item):
46 '''
47 当调用in,not in ,会自动调用该方法判断链接对应网址是否在数据库中
48 :param item: 下载的url链接(路由)
49 :return:
50 '''
51 try:
52 self[item] #这一步会调用__getitem__,找不到__getitem__会抛出异常,在这里进行捕获异常只返回False,否则返回True
53 except KeyError:
54 return False
55 else:
56 return True
57
58 def clear(self):
59 '''
60 清空该集合中的数据
61 :return:
62 '''
63 self.db.webpage.drop()
64
65 class TiebaMongo(TiebaSpider):
66 def save_result(self, result,url_str):
67 """
68 重写父类的该方法,将数据保存到数据库
69 :param result:
70 :param url_str:
71 :return:
72 """
73 mc = MongoCache()
74 mc[url_str] = result
75
76 def run(self):
77 url_lists = self.make_url()
78 for url_str in url_lists:
79 result_str = self.download_url(url_str)
80 self.save_result(result=result_str,url_str=url_str)
81
82 # class QiushiMongo(QiushiSpider):
83 # def save_result(self, result,url_str):
84 # mc = MongoCache()
85 # mc[url_str] = result
86 #
87 # def run(self):
88 # url_lists = self.make_url()
89 # for url_str in url_lists:
90 # result_str = self.download_url(url_str)
91 # self.save_result(result=result_str,url_str=url_str)
92
93 # if __name__ == '__main__':
94 #爬取贴吧并存到MongoDB
95 # test = TiebaMongo('lol')
96 # test.run()
97 #爬取糗事并存到MongoDB
98 # qiushi = QiushiMongo()
99 # qiushi.run()
100 #查询MongoDB
101 # mc = MongoCache()
102 # print(mc['https://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=2'])
103 # print('https://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=3' in mc)
104 # cha = MongoCache()
105 # print(cha[test.url_base])
106 # print(mc["https://www.qiushibaike.com/8hr/page/2/"])