由于在爬虫时, 可因为各种原因导致爬虫在爬取页面的时候从中间断开连接, 当再次爬取的时候不知道从什么地方开始, 这里利用mongodb封装一个类, 用来监控哪些网页已经爬取过, 哪些没有爬取, 为以后监控提供方便.
创建一个mongo_cache.py的文件, 具体代码如下
import pickle
import zlib
from datetime import datetime, timedelta
from pymongo import MongoClient
from bson.binary import Binary
class MongoCache():
"""
数据库缓存
Cache,是一种后关系型数据库。能并发访问同一数据的数据库技术.
"""
# expires到期时间 timedelta时间间隔
def __init__(self, client=None, expires=timedelta(days=30)):
self.client = MongoClient("localhost", 27017)
self.db = self.client.cache
# 创建索性, 方便快速查询, 设置超时时间, 如果达到expireAfterSeconds设置的超时时间, mongodb会把超时数据自动删除
self.db.webpage.create_index("timestamp", expireAfterSeconds=expires.total_seconds())
def __setitem__(self, key, value):
# 压缩数据, 设置时间戳
record = {"result": Binary(zlib.compress(pickle.dumps(value))), "timestamp": datetime.utcnow()}
# 查询数据库, 没有就插入, 有就更新该数据
# 使用updata的upset(如果不存在执行insert, 存在执行updata)参数进行插入更新操作, $set内置函数表示覆盖原始数据
self.db.webpage.update({"_id": key}, {"$set": record}, upsert=True)
def __getitem__(self, item):
# 根据_id以item作为关键字(例如url: http://www.baidu.com)查询相关网页
record = self.db.webpage.find_one({"_id": item})
if record:
# 解压缩
return pickle.loads(zlib.decompress(record["result"]))
else:
# 找不到抛出异常
raise KeyError(item + "does not exist")
def __contains__(self, item):
try:
self[item] # 这里会调用__getitem__方法
except KeyError:
return False # 捕获到keyError异常说明没有找到相关数据, 参考36行抛出异常的条件
else:
return True # 找到相应数据库说明数据库包含下载内容
def clear(self):
# 将缓存清空
self.db.webpage.drop()
在以后要监控别的页面的时候, 只需要调用这个类的方法就可以了.