Python 爬虫时如何高效地进行链接去重

第一步,爬取链接存储到 MongoDB 中 第二步,爬取每个链接的详细信息,存储爬取成功的链接及信息

第二步爬取的过程不会很顺利,有时需要计算未完成的链接,再进行爬取,我目前是这样处理的 把第一步的链接存储在 list 里,再转成集合( set) 把第二步的链接存储在 list 里,再转成集合( set) 未完成的链接 = 第一步的 set - 第二步的 set

遇到的问题是,如果链接数比较小的时候,这样处理速度比较快,当链接数达到几百万时,这样处理的速度不是很理想,请问有没有高效的处理方法呢?


Python 爬虫时如何高效地进行链接去重

13 回复

用 redis 去重比较粗暴


用集合(set)或布隆过滤器(Bloom Filter)。

集合简单直接,适合数据量不大(比如百万级)的情况:

seen_links = set()
new_links = ['http://example.com', 'http://example.com/page1', 'http://example.com']
for link in new_links:
    if link not in seen_links:
        seen_links.add(link)
        # 处理链接

如果链接量极大(上亿级别),用内存友好的布隆过滤器,比如 pybloom-live

from pybloom_live import BloomFilter

bf = BloomFilter(capacity=1000000, error_rate=0.001)
new_links = ['http://example.com', 'http://example.com/page1', 'http://example.com']
for link in new_links:
    if link not in bf:
        bf.add(link)
        # 处理链接

简单总结:量小用集合,量大上布隆过滤器。

布隆过滤器

最近在爬一个站,第一步的数据存数据库了, django 下面放一个 scrapy 存取去重很方便,第二步用第一步的数据,使用 celery 的 task 定时爬取 我的第二步是下图片 所以开了好几台小机器分开下载的,下载结果直接修改 主数据库;缺点是数据库访问有点频繁,负载有点高~ 感觉 django + scrapy + celery 做类似的项目简直是爽~

https://github.com/rolando/scrapy-redis
目前用 redis 去重,抓了微信,微博,网站,视频总共加载一块得 1000+个,用的很丝滑。

赞, 布隆过滤器是标准做法

bloomfliter 有一定概率产生错误,要看下业务能不能允许这种情况

谢啦,我去查查这方面的资料

十分感谢!

谢啦!:)

感谢!

我去研究一下,谢谢!

回到顶部