一般大家用什么办法判断 url 已经被爬过了? 用 hashmap 感觉内存消耗无上限啊,几十 G 内存唰唰唰就满了,用 sqlite 感觉 HDD 会成瓶颈?
1
wmttom 2017 年 3 月 9 日 via iPhone
bloom filter
|
2
cdwyd 2017 年 3 月 9 日 via Android
吓一跳,看成了爬虫重判
|
3
cdwyd 2017 年 3 月 9 日 via Android
hashmap 也不会嗖嗖几十个 g 吧,检查下流程,是不是哪里错了。
|
4
gouchaoer 2017 年 3 月 9 日 via Android
数据库加索引就完了,搞那么复杂
|
5
jiangzhuo 2017 年 3 月 9 日 首先大家应该是用 url 判重,一般是选取 hostname 、 path 和一部分或者全部的 query 来组合进行 hash 判重。
就拿把 hash 作为 key 以 string 类型存在 redis 中来说。 计算出来的 key 的 sds 大小是 64 字节,值只有 1 字节, sds 大小 16 字节。 在没有修改 redis 配置的情况下。 然后根据 http://www.worldwidewebsize.com/ Google 索引 47 亿多一点 如果有 47 亿个不同的 url 的话,占用内存是 4700000000*( 16+16+16+64 )+8589934592*4 = 522.25G (卧槽,打自己脸了 再算算 如果楼主爬 5 亿个不同网址,大概需要 54G 的 redis ,这应该是一般能买的起的 64G 或者 96G 内存的机器。 5 亿个网址好像也超过现在的必应了。 |
6
scnace 2017 年 3 月 9 日 via Android
Bloomfilter 或 数据库加索引
|
7
samcode 2017 年 3 月 9 日 先 crc 或者啥 hash 一下
|
9
1a1a11a OP 检查过了,主要是 url 数据量太大了,写入磁盘的已经几百 GB 了,不过有些 url 是没意义的,需要想办法过滤掉。
|
12
1a1a11a OP @jiangzhuo 为什么我 72G 的内存刷刷刷就满了 :(,估计有不少费 url ,加上 python 可能比较费内存,你发的这个网址挺好玩的,不知道为什么中间突然降下去了,我一直觉得网页总数是单调增加的,不过从这个网站看,还挺稳定的。
|
14
binux 2017 年 3 月 9 日
@1a1a11a #9 你已经写磁盘了?没有去重就已经写磁盘了?那么看起来你并没有实时去重的需求啊。那简单,把 url 排个序 sort | uniq 就行了。
|
15
bjlbeyond 2017 年 3 月 9 日 via iPhone
对爬取过的 url 计数,超过一定次数后丢弃
|
16
wmttom 2017 年 3 月 9 日 via iPhone @1a1a11a 很多时候几个 9 的准确性已经足够了。
或者可以利用 Bloomfilter 的特性,不存在的一定不在,存在的再去查询存储索引,看是不是真的存在。 |
17
Lax 2017 年 3 月 9 日
用 HLL ,内存占用很少,有些误差
|
18
v2pro 2017 年 3 月 9 日 simhash
|
21
allgy 2017 年 3 月 9 日
#1 楼正解
|
27
Lax 2017 年 3 月 11 日 @1a1a11a HyperLogLog , redis 内置支持 https://redis.io/commands/pfadd
|