1. 程式人生 > >用mongodb資料庫, 對爬取的頁面進行監控(mongo_cache)和資料儲存

用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()

在以後要監控別的頁面的時候, 只需要呼叫這個類的方法就可以了.