听说你的爬虫一直在整站里循环绕圈圈爬取重复的数据? by 帅彬Posted on2019-09-182020-02-12 今天 小帅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高手之路」 原文始发于微信公众号(学习python的正确姿势):python