我目前正在使用Python编码的爬虫程序,结合使用Gevent / requests / lxml来抓取定义的一组页面。我使用redis作为数据库来保存列表,例如挂起队列,提取和已爬网的站点。对于每个网址,我都有一个密钥url_,我使用SETNX命令确保该网址尚未被抓取,然后将其放入队列。
我开始面临的一个问题是,url_键开始增长非常快,Redis几乎将所有数据保存在内存中,因此很快就会成为一个问题。被抓取的网址没有到期时间,因为我只需要访问它们一次,并且网址的内容将来不会更改,因此我仍然希望保留所有访问过的网址。 (我过滤了很多重复的URL)是否可以在Redis中使用一些数据结构,如cuckoo哈希表或bloom过滤器,这样我就可以防止访问过的URL列表快速增长并仍然受益查询队列时的速度?
是否有一些替代方法可用于确定URL是否已被访问过?解决方案应该是可伸缩和分布式的,因为爬网程序当前正在多台计算机上运行。 谢谢!
答案 0 :(得分:1)
一些建议:
使用Redis' (2.8.9 +)HyperLogLog data structure - 您可以使用PFADD
和PFCOUNT
来获取合理的答案,无论之前是否计算过网址。
不要将每个网址保留在自己的url_
密钥中 - 按照"Memory Optimization/Using hashes to abstract a very memory efficient plain key-value store on top of Redis"
将访问过的网址存储在一个(几个分段)集中,用于历史查找和自动重复数据删除。使用排序集,将网址分数设置为其抓取时间的纪元值,以便对其进行排序并进行范围查询。
结论:除非您使用url_
键实际存储有关网址的内容,否则请不要这样做。您似乎只是为了管理状态而使用这些键,因此哈希和集合会更有效和更强大。