初识 python 装饰器 以及 通过url去重
今天写爬虫遇到去重问题。在管理多个爬虫时,单独写函数太过冗余,想起了原来带我做项目的大哥极力推荐的装饰器!自己也来试试
主要目的是通过set对爬取的网页进行去重,爬取前检查是否网页是否已经在redis中,确认执行完函数后插入redis,初稿如下
def url_filter(func):
def wrapper(*args):
redis_conn = get_redis()
url = args[0]
if not redis_conn.sismember('block', url):
func(*args)
redis_conn.sadd('block', url)
return wrapper
针对不同的爬虫,需要单独命名,所以加入装饰器传参
def url_filter(web_name):
def decorator(func):
def wrapper(*args):
redis_conn = get_redis()
url = args[0]
if not redis_conn.sismember(web_name, url):
func(*args)
redis_conn.sadd(web_name, url)
return wrapper
return decorator
网上查了下,使用MD5加密可以压缩存储空间,所以将传入的网址进行MD5在存入redis,并根据被装饰函数返回值,确定是否需要入库
def url_filter(web_name):
def decorator(func):
def wrapper(*args):
redis_conn = get_redis()
url = args[0]
md5_url = hashlib.md5(url).hexdigest()
if not redis_conn.sismember(web_name, md5_url):
res = func(*args)
if res:
redis_conn.sadd(web_name, md5_url)
return wrapper
return decorator
定义在一个请求上方
@url_filter('block')
def get_project_message(url, data):
r = session.get(url)
if r.status_code == 200:
parse_project_message(r.content, data)