凤凰体育平台 删除爬虫网址,妈妈永远不会担心我不会再做

日期:2021-01-15 15:03:57 浏览量: 110

URL重复数据删除

为什么在共同搜寻时需要执行URL重复数据删除?

URL重复数据删除和策略简介

表面上,URL重复数据删除策略是一种消除URL重复的方法。常见的URL重复数据删除策略有以下四种:

# 1.将访问过的ur保存到数据库中
# 2.将访问过的ur保存到set(集合)中,只需要o(1)的代价就可以查询url
#       10000000*2byte*50个字符/1024/1024/1024=9G
# 3.url经过md5等方法哈希后保存到set(或者Redis中)中
# 4. bloomfilter方法对 bitmap进行改进,多重hash函数降低冲突

方法1:将访问的ur保存到数据库中

最简单的实现澳洲欢乐8app ,但效率最低。核心思想是将页面上爬网的每个URL存储在数据库中。为了避免重复,有必要在每个存储之前遍历并查询数据库中的当前URL(即是否已被爬网)(如果存在)万狗体育乐鱼体育 ,请不要保存,否则,请保存当前URL并继续保存下一个直到最后。

方法2:将访问的ur保存到设置的存储器中

实现很简单url去重,原理类似于第一种方法。此方法访问方便,基本上不需要搜索。但是,如果URL过多,则会占用大量内存并浪费空间。

# 简单计算:假设有1亿条url,每个url平均长度为50个字符,python里unicode编码,每个字符16位,占2
# 个字节(byte)
# 计算式:10^8 x 50个字符 x 2个byte / 1024 / 1024 / 1024 = 9G
#                                    B      M      G
如果是2亿个url,那么占用内存将达18G,也不是特别方便,适合小型爬虫。

方法三.该url由md5和其他方法进行哈希处理yabobet ,然后保存为set(或Redis)(实现方法如下)

简单计算:一个url经MD5转换,变成一个128bit()的字符串,占16byte(字节),方法二中一个url保守估
计占50个字符 x 2 = 100byte(字节)
计算式: 这样一比较,MD5的空间节省率为:(100-16/100 = 84%(相比于方法二)
(Scrapy框架url去重就是采用的类似方法)
    def request_fingerprint(self, url):
        """Returns a fingerprint for a given url
        Parameters
        ----------
        url : 待请求的url地址
        Returns: str
        """
        #根据url生成指纹
        print('未加密之前:',url)
        md5_obj = hashlib.md5()
        # 进行MD5加密前必须 encode(编码),python里默认是unicode编码,必须转换成utf-8
        # 否则报错:TypeError: Unicode-objects must be encoded before hashing
        md5_obj.update(url.encode(encoding='utf-8'))
        md5_url = md5_obj.hexdigest()
        print('MD5加密后:',md5_url)
        return md5_url

方法4:bloomfilter方法改进了位图,并且多个哈希函数减少了冲突。

原理概述:布隆过滤器的原理是url去重,将元素添加到集合中时,该元素通过K个哈希函数映射到位数组中的K个点,并且它们设置为1。在搜索时,我们仅需要检查这些点是否全部为1(大约),以了解集合中是否存在任何这些点:如果这些点具有任何0,则被检查元素必须不存在。如果它们全部为1,则可能是被检查元素。这是布鲁姆过滤器的基本思想。

url去重

利弊

# 设置散列函数的个数
BLOOMFILTER_HASH_NUMBER = 6
# 布隆过滤器设置bit参数,默认30,占用128M空间,去重量在1亿左右
此参数决定了位数组的位数,如果BLOOMFILTER_BIT为30,则位数组
230次方,这将暂用Redis 128MB的存储空间url去重数量在1亿左右
如果爬取的量在10亿,20亿或则更高,则需要将此参数调高
BLOOMFILTER_BIT = 30
class HashMap(object):
    def __init__(self, m, seed):
        self.m = m
        self.seed = seed
    def hash(self, value):
        """
        Hash Algorithm
        :param value: Value
        :return: Hash Value
        """
        ret = 0
        for i in range(len(value)):
            ret += self.seed * ret + ord(value[i])
        return (self.m - 1) & ret
class BloomFilter(object):
    def __init__(self, server, key, bit=BLOOMFILTER_BIT, hash_number=BLOOMFILTER_HASH_NUMBER):
        """
        Initialize BloomFilter
        :param server: Redis Server
        :param key: BloomFilter Key
        :param bit: m = 2 ^ bit
        :param hash_number: the number of hash function
        """
        # default to 1 << 30 = 10,7374,1824 = 2^30 = 128MB, max filter 2^30/hash_number = 1,7895,6970 fingerprints
        self.m = 1 << bit
        self.seeds = range(hash_number)
        self.server = server
        self.key = key
        self.maps = [HashMap(self.m, seed) for seed in self.seeds]
    def exists(self, value):
        """
        if value exists
        :param value:
        :return:
        """
        if not value:
            return False
        exist = True
        for map in self.maps:
            offset = map.hash(value)
            exist = exist & self.server.getbit(self.key, offset)
        return exist == 1
    def insert(self, value):
        """
        add value to bloom
        :param value:
        :return:
        """
        for f in self.maps:
            offset = f.hash(value)
            self.server.setbit(self.key, offset, 1)

按如下所述单独使用

client = redis.StrictRedis(host='118.24.255.219',port=6380)
    bl = BloomFilter(client,'bl:url')
    url = 'http://www.wanfangdata.com.cn/details/detaype=conference&id=7363410'
    bl.insert(url)
    result = bl.exists(url)
    print(result)
    url1 = 'http://www.wanfangdata.com.cn/details/detaype=conference&id=73634101'
    result = bl.exists(url1)
    print(result)

为方便使用辛运28 ,我们还可以连接scrpay-redis。无需重新发明轮子。我们可以直接使用pip3来安装ScrapyRedisBloomFilter:-安装

pip3 install scrapy-redis-bloomfilter

# Ensure use this Scheduler(使用自定义的调度器组件)
SCHEDULER = "scrapy_redis_bloomfilter.scheduler.Scheduler"
# Ensure all spiders share same duplicates filter through redis(使用自定义的去重组件)
DUPEFILTER_CLASS = "scrapy_redis_bloomfilter.dupefilter.RFPDupeFilter"
# Redis URL(设置去重指纹需要保存的redis数据库信息)
REDIS_URL = 'redis://:foobared@localhost:6379'
# Number of Hash Functions to use, defaults to 6
#设置散列函数的个数
BLOOMFILTER_HASH_NUMBER = 6
# Redis Memory Bit of Bloomfilter Usage, 30 means 2^30 = 128MB, defaults to 30
# 布隆过滤器设置bit参数,默认30,占用128M空间,去重量在1亿左右
此参数决定了位数组的位数,如果BLOOMFILTER_BIT为30,则位数组
230次方,这将暂用Redis 128MB的存储空间url去重数量在1亿左右
如果爬取的量在10亿,20亿或则更高,则需要将此参数调高
BLOOMFILTER_BIT = 30
# Persist
#是否支持断点爬取
SCHEDULER_PERSIST = True

实际上,ScrapyRedisBloomFilter基于scrapy-redis来判断和修改DUPEFILTER重复数据删除组件的重复数据删除部分,如下图所示:

url去重

url去重

研究完此摘要后,您不必担心网址重复!