scrapy使用布隆过滤器实现增量爬取

scrapy使用布隆过滤器实现增量爬取

以前看了不少关于scrapy-redis使用bloomfilter进行持久化存储进行url去重的例子,但是发现没有一种适用于scrapy,因而萌生了基于现有scrapy-redis-bloomfilter库进行改写的想法。web

通过修改,此脚本能够作一个初步的文本内容去重redis

言归正传,直接上代码:scrapy

settings.py

# 散列函数的个数,默认为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'

spiders.py

#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