在掘金社区发布文章,并在正文的第一句加入“我正在参加「掘金·启航计划」”
写在前面
今天是第 78 篇 Python 爬虫博客了,在这里立个 Flag,争取在 10 月 1 日之前把爬虫百例写完,如果你从第一篇看到现在,你应该是一个合格的爬虫 Coder 了,继续加油!!
继续搞定增量爬虫,本文涉及两个 Python 模块,一个为 Scrapy,另一个是 BloomFilter
BloomFilter(布隆过滤器)使用场景
关于 BloomFilter 是谁发明的以及为什么发明,本文就不在赘述了,下面主要给大家分享一下 BloomFilter 使用的场景
- 黑名单应用(邮件黑名单)
- 网络爬虫去重(和我们要学的增量爬虫产生了关联)
- KV 系统快速判断 Key 是否存在
- 减少缓存穿透(具体没尝试过,不做过多的解释,可以参照: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 版本,下载即可,该内容的安装在之前的博客中我们已经说明过,这里不再赘述,看截图找命令即可
![](/qrcode.jpg)
步骤一:
步骤二:
安装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…
写在后面
今天的增量爬虫就到这里了,希望本文能对你有所帮助~