之前看了很多关于scrapy-redis使用bloomfilter进行持久化存储进行url去重的例子,可是发现没有一种适用于scrapy,于是萌生了基于现有scrapy-redis-bloomfilter库进行改写的想法。
经过修改,此脚本可以做一个初步的文本内容去重
言归正传,直接上代码:
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包,确实让我能够偷懒不少!~
如需转载,请注明出处!~谢谢配合!