听说你的爬虫一直在整站里循环绕圈圈爬取重复的数据?

今天
小帅b要跟你说说
增量爬虫
是这样的
当你去爬取某个网站的数据时
你会发现
这些网站随着时间的推移
会更新更多的网页数据
这时候你要爬取的是
那些更新的网页数据
而不是
又一次爬取整站的内容
对于一些稍微复杂点的网站
它们的 url 之间会指来指去
如果你根据 url 的定向去爬取
可能会出现这种情况
你的爬虫一直在里面绕圈圈
一直爬取重复的数据
这时候你的爬虫
开始陷入了对人生的大思考
那么如何确保
爬取的数据不要重复?
接下来就是
学习 python 的正确姿势

有朋友说
那就直接用数据库呗
在爬取前
把 url 存入数据库
下次爬取的时候
再到数据库里面查询
看下这个 url 是否存在数据库
如果存在
那就说明
这个 url 之前已经被爬取过了
如果不存在
就把 url 保存到数据库中
这种方式虽然可行
但是如果数量一多
查询速度就会大大降低
从而影响爬取效率了
其实
python 中有一个
我们熟悉的数据结构
set
set 里面的元素是唯一不重复的
所以我们可以将 url 塞进去
下次通过 in 来判断就可以了
因为它的平均复杂度为 O(1)
这样就比数据库的操作高效很多了
但是
这种方式有一个问题
使用 python 的 set
是作用于内存的
一旦 url 的数量增多
就会很耗内存
不知道你还记得咱们之前说的这个
如果你怕文件被篡改,那就这样做
在这里面咱们说到了 hash
通过散列可以生成唯一的指纹
那么这时候
我们可以使用 url 进行 hash
比如进行 MD5 加密
由于 MD5 值所占的内存更小
所以可以通过 MD5 来降低 url 的内存
也就是说
直接把 url 进行 MD5
然后把得到的 MD5
放进 set 就好了
可以做到缩短 url 的
长度来降低内存的消耗
当然了
还有与之类似的
redis
redis 中也有和 Python 相似的 set
我们可以使用它来存储 url 的 MD5
这种缓存数据库的优点在于
它可以作用于硬盘
不会有消耗内存的压力
而对于海量数据的情况
我们可以考虑使用
bloom filter
它的操作方式是这样的
使用 k 个 hash 函数
来对集合中的 url 映射成
位数组中的 k 个点
然后把他们置 1
下次查询的时候
只要通过 hash 看看这个
url 的结果是不是都是 1
如果都是 1
这个 url 就可能存在
如果有任何一个 0
就说明这个 url 一定不存在
懵逼了?
我来画个图吧
一开始是这样的
假设我们集合有 n 个 url
这里初始化了位数组
都是0
接着对集合中的 url 都进行 k 个 hash
这里以 url4 为例
可以看到
hash 之后映射到 1
当下次要判断新的 url 是否在集合中的时候
就可以使用 hash 去查找
只要发现有 0
那么就说明这个 new_url
一定不存在于集合中
这样的方式可以节省超多的空间
提高了空间的利用率
在 python 中
早有实现了 bloomfilter 的库
pybloom
可以自己定义容量和容错率

使用 add 方法

如果元素存在就直接返回 True

如果不存在就返回 False

此外

还可以使用动态容量的方式

ok
通过以上这些方法
对于数据的去重
相信你应该知道怎么做了
那么
我们下回见啦
peace

扫一扫

学习 Python 没烦恼

ps:如果你想获取更多小帅b提供的私密非公开且纯净无广告的干货 vip 教程,可以了解一下:跟小帅b一起通往「Python高手之路」
(0)

相关推荐