import os
import re
import urllib.parse
import pickle
class DiskCache:
def __init__(self,cache_dir='cache'):
self.cache_dir=cache_dir
def __getitem__(self, item):
'''获取缓存'''
path=self.url_to_path(item)
if os.path.exists(path):
with open(path,'wb')as fp:
return pickle.load(fp)
else:
raise KeyError(url+' dose not exist!')
def __setitem__(self, key, value):
'''保存缓存'''
path=self.url_to_path(key)
folder=os.path.dirname(path) #返回dirname目录
if not os.path.exists(folder): #没有父目录则创建父目录
os.makedirs(folder)
with open(path,'wb') as fp: #写入子文件
fp.write(pickle.dumps(value))
def url_to_path(self,url):
'''为url创建path'''
components=urllib.parse.urlparse(url)
path=components.path
# 主要是避免特殊情况,可以视情况而定
'''
if not path:
path='/start' #如果url没有path就创建一个
elif path.endswith('/'):
path+='no_end'
'''
filename=components.netloc+path+components.query
#替换文件名中的不合法部分
filename=re.sub('[^/0-9a-zA-Z\-.,;_]','_',filename)
filename='/'.join(segment[:255] for segment in filename.split('/'))#创建多级目录
return os.path.join(self.cache_dir,filename)
#添加压缩减少磁盘占用,但是会加大一点查询时间,不过无关紧要
#在加一个缓存过期
import os
import re
import urllib.parse
import pickle
import zlib
import datetime
from datetime import timedelta
class DiskCache:
def __init__(self,cache_dir='cache',expire=timedelta(days=30)):
self.cache_dir=cache_dir
self.expire=expire
def __getitem__(self, item):
'''获取缓存'''
path=self.url_to_path(item)
if os.path.exists(path):
with open(path,'wb')as fp:
result,time=pickle.load(zlib.decompress(fp.read()))
if self.has_expire(time):
raise KeyError(url+' has expired!')
return result
else:
raise KeyError(url+' dose not exist!')
def __setitem__(self, key, value):
'''保存缓存'''
path=self.url_to_path(key)
folder=os.path.dirname(path) #返回dirname目录
if not os.path.exists(folder): #没有父目录则创建父目录
os.makedirs(folder)
time=datetime.datetime.utcnow()
with open(path,'wb') as fp: #写入子文件
fp.write(zlib.compress(pickle.dumps(value,time)))
def has_expire(self,timestamp):
return datetime.datetime.utcnow()>timestamp+self.expire
def url_to_path(self,url):
'''为url创建path'''
components=urllib.parse.urlparse(url)
path=components.path
# 主要是避免特殊情况,可以视情况而定
'''
if not path:
path='/start' #如果url没有path就创建一个
elif path.endswith('/'):
path+='no_end'
'''
filename=components.netloc+path+components.query
#替换文件名中的不合法部分
filename=re.sub('[^/0-9a-zA-Z\-.,;_]','_',filename)
filename='/'.join(segment[:255] for segment in filename.split('/'))#创建多级目录
return os.path.join(self.cache_dir,filename)