用mongodb数据库, 对爬取的页面进行监控(mongo_cache)和数据保存

由于在爬虫时, 可因为各种原因导致爬虫在爬取页面的时候从中间断开连接, 当再次爬取的时候不知道从什么地方开始, 这里利用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()

在以后要监控别的页面的时候, 只需要调用这个类的方法就可以了.

猜你喜欢

转载自blog.csdn.net/qq_42827960/article/details/85094595