以前看了不少关于scrapy-redis使用bloomfilter进行持久化存储进行url去重的例子,但是发现没有一种适用于scrapy,因而萌生了基于现有scrapy-redis-bloomfilter库进行改写的想法。web
通过修改,此脚本能够作一个初步的文本内容去重redis
言归正传,直接上代码:scrapy
# 散列函数的个数,默认为6,能够自行修改 BLOOMFILTER_HASH_NUMBER_URL = 6 # Bloom Filter的bit参数,默认30,占用128MB空间,去重量级1亿 BLOOMFILTER_BIT_URL = 30 # redis链接方式 REDIS_URL = 'redis://user:password@host:port/0'
#code by Kirinshy import scrapy from gne import GeneralNewsExtractor from scrapy.utils.project import get_project_settings from redis import Redis from scrapy_redis_bloomfilter.bloomfilter import BloomFilter class CrawlerSpider(scrapy.Spider): name = 'crawler' settings = get_project_settings() server = Redis.from_url(settings.get("REDIS_URL")) def start_requests(self): url_list = [] for url in url_list: #使用布隆过滤器进行去重 if not self.dul_url_bf(url,'url_finger'): yield scrapy.Request(url,callback=self.parse_detail) def parse_detail(self,response): content = response.xpath().extract_first() #使用布隆过滤器进行去重 if not self.dul_url_bf(content,'content_finger'): print(content) #此处传入url,或者文本正文,key能够传递指纹名称 def dul_url_bf(self, url , key): ''' url去重,若是url已经存在返回True,反之把url写入bloomfilter,并返回False(bf组件的exist()存在的时候返回1, 不存在返回false) :param url: :return: 若是存在返回True,不存在返回False ''' bf = BloomFilter(server=self.server, key= key, hash_number=self.settings.get("BLOOMFILTER_HASH_NUMBER_URL"), bit=self.settings.get("BLOOMFILTER_BIT_URL")) if bf.exists(url): print(f'dupeurl:{url}') return True else: bf.insert(url) return False
以上即是须要修改的代码,另感谢崔大以前发布的scrapy-redis-bloomfilter包,确实让我可以偷懒很多!~ide
如需转载,请注明出处!~谢谢配合!svg