用裝飾器實現(xiàn)了一個為現(xiàn)有爬蟲實現(xiàn)本地緩存功能的模塊,只需要引入這個spidercache.py文件,然后在爬蟲下載文件的方法頂部添加@cache(cachetime=3600)即可,唯一的參數(shù)就是緩存過期時間(秒)。代碼兼容py2和py3。
爬蟲下載文件的方法必須是傳入一個地址,輸出文本或者字節(jié)內(nèi)容,下面案例方法是返回的是處理后的title,那么緩存的也同樣是title。如果直接返回的是html,那么就是緩存整個html文件。
爬蟲運行后會自動在當(dāng)前目錄下創(chuàng)建.cache文件夾存放緩存。

Paste_Image.png
使用案例:
spider.py
import requests
import re
from spidercache import cache
@cache(cachetime=3600)
def get_html(url):
r = requests.get(url)
r.encoding = 'utf8'
html = r.text
reg = re.compile(r'<title>(.*?)</title>',re.S)
title = reg.search(html).group(1)
return title
title = get_html('http://www.baidu.com')
print(title)
spidercache.py
# -*- coding: utf-8 -*-
# Copyright (c) 2017 - walker <cail1844@gmail.com>
import hashlib
import os
from functools import wraps
import codecs
import time
def cache(cachetime):
def decorator(func):
@wraps(func)
def wrapper(*args):
url = args[0]
hash = hashlib.md5()
hash.update(url.encode('utf8'))
md5 = hash.hexdigest()
cachedir = os.path.join('.cache',md5[0:2],md5[2:4])
cachepath = os.path.join('.cache',md5[0:2],md5[2:4],md5)
try:
mtime = os.path.getmtime(cachepath)
if time.time() - mtime > cachetime:
raise Exception('cache time expired')
else:
print(url,'read cache')
with codecs.open(cachepath,'r','utf8') as f:
data = f.read()
return data
except Exception as e:
print(url,'get content from internet',e)
if not os.path.exists(cachedir):
os.makedirs(cachedir)
data = func(url)
with codecs.open(cachepath,'w+','utf8') as f:
f.write(data)
return data
return wrapper
return decorator