2022爬虫课,用Scrapy+BloomFilter再写个增量爬虫

1,168 阅读4分钟

在掘金社区发布文章,并在正文的第一句加入“我正在参加「掘金·启航计划」”

写在前面

今天是第 78 篇 Python 爬虫博客了,在这里立个 Flag,争取在 10 月 1 日之前把爬虫百例写完,如果你从第一篇看到现在,你应该是一个合格的爬虫 Coder 了,继续加油!!

继续搞定增量爬虫,本文涉及两个 Python 模块,一个为 Scrapy,另一个是 BloomFilter

BloomFilter(布隆过滤器)使用场景

关于 BloomFilter 是谁发明的以及为什么发明,本文就不在赘述了,下面主要给大家分享一下 BloomFilter 使用的场景

  1. 黑名单应用(邮件黑名单)
  2. 网络爬虫去重(和我们要学的增量爬虫产生了关联)
  3. KV 系统快速判断 Key 是否存在
  4. 减少缓存穿透(具体没尝试过,不做过多的解释,可以参照:blog.itpub.net/31561269/vi… 博客内容)

今天需要掌握的一个库叫做pybloom_live 关于它的源码,最新的版本参照 pypi.org/project/pyb…

首先去 github 查阅一下依赖库,这个地方蛮重要的,如果不注意后续很容易翻车github.com/joseph-fox/… 在依赖库中查阅到需要一个bitarray

在这里插入图片描述

由于一开始我未安装,出现如下错误,注意一下,提示我们 VC++14 不存在,但安装它非常耗费资源,我们可以通过其他办法进行

在这里插入图片描述

打开https://www.lfd.uci.edu/~gohlke/pythonlibs/#bitarray 找到你电脑本地安装的 Python 对应的版本,我使用的是 3.7 版本,下载即可,该内容的安装在之前的博客中我们已经说明过,这里不再赘述,看截图找命令即可

在这里插入图片描述

步骤一:

在这里插入图片描述

步骤二:

安装pybloom_live

在这里插入图片描述

pybloom_live 快速入门

pybloom_live 存在两种简单的用法,BloomFilter 定容与 ScalableBloomFilter 可伸缩的,说白了就是一个固定的一个动态扩展的。

上面是我抛的砖(百度一下,基础的说明还是非常多的)

接下来我们通过BloomFilter 类,去操作一个文件,实现去重,这个地方注意一下,BloomFilter是通过读写文件的方式进行去重,如果你编写多进程或者多线程爬虫,使用的时候需要添加互斥和同步条件,还有BloomFilter涉及文件 I/O 操作,注意批量写入和批量读取,否则效率会有很大的影响。

声明一个bloomcheck.py类文件,编写如下代码,代码说明已经放在注释中

from pybloom_live import BloomFilter
import os
import hashlib
class BloomCheck(object):
    def __init__(self):
        '''
        以下代码用于判断bf布隆文件是否存在,存在打开,不存在新建
        '''
        self.filename = 'bloomfilter.bf'
        is_exist = os.path.exists(self.filename)
        if is_exist:
            self.bf = BloomFilter.fromfile(open(self.filename, 'rb'))
        else:
            # capacity是必选参数,表示容量 error_rate是错误率
            self.bf = BloomFilter(capacity=100000000, error_rate=0.001)

    def process_item(self, data):
        data_encode_md5 = hashlib.md5(data.encode(encoding='utf-8')).hexdigest()
        if data_encode_md5 in self.bf:
            # 如果data存在,返回False
            return False

        else:
            # 如果data不存在,新增到bf文件中,返回True
            self.bf.add(data_encode_md5)
            return True

    def save_bloom_file(self):
        self.bf.tofile(open(self.filename, 'wb'))

scrapy 爬虫代码

对于基础爬虫部分,只对核心爬虫源码部分做展示,对于response的解析,依旧是先进行基础的判断,如果title已经存在bf文件(该文件是上述代码动态创建的)中,那么不增加,否则迭代数据

完整代码会上传到附件中,文章末尾可以进行下载

class IndexSpider(scrapy.Spider):
    name = 'index'
    allowed_domains = ['xz.aliyun.com']
    start_urls = ['http://xz.aliyun.com/']
    bf = BloomCheck()
    def parse(self, response):
        li_list = response.xpath("//a[@class='topic-title']")
        for li in li_list:
            de_item = DeItem()
            title = li.xpath("./text()").extract_first().strip()
            # 判断title是否在bf文件中,如果不在,返回新数据
            if self.bf.process_item(title):
                de_item['title'] = title
                de_item['url'] = "https://xz.aliyun.com" + li.xpath("./@href").extract_first()
                yield de_item
            else:
                print(f"--{title}--数据已经存在,不进行添加")

        # 保存数据
        self.bf.save_bloom_file()

设置 scrapy 定时任务

写一个 run.bat 批处理文件,放在与爬虫程序同一个目录,其他目录也可以
下面的路径注意更换到自己的路径即可

@echo off
rem
E:
cd E:\crawl100\demo78\de\de

scrapy crawl index
rem pause
exit

定制 windows 定时任务计划 在“控制面板”下的“管理工具”下面找到“任务计划程序”并打开 创建基本任务, 在启动程序后,选择 bat 文件所在位置。 计划任务在测试的时候注意一下时间即可。

在这里插入图片描述

这个地方给大家找到一篇写的比较细的博客,内容比较简单,不在赘述:blog.csdn.net/Gpwner/arti…

写在后面

今天的增量爬虫就到这里了,希望本文能对你有所帮助~