1a1a11a
V2EX  ›  编程

爬虫判重

  •  
  •   1a1a11a · Mar 9, 2017 · 6204 views
    This topic created in 3530 days ago, the information mentioned may be changed or developed.

    一般大家用什么办法判断 url 已经被爬过了? 用 hashmap 感觉内存消耗无上限啊,几十 G 内存唰唰唰就满了,用 sqlite 感觉 HDD 会成瓶颈?

    28 replies  •  2017-03-12 03:37:30 +08:00
    wmttom
    wmttom
    Mar 9, 2017 via iPhone
    1
    bloom filter
    cdwyd
    cdwyd
    Mar 9, 2017 via Android
    2
    吓一跳,看成了爬虫重判
    cdwyd
    cdwyd
    Mar 9, 2017 via Android
    3
    hashmap 也不会嗖嗖几十个 g 吧,检查下流程,是不是哪里错了。
    gouchaoer
    gouchaoer
    Mar 9, 2017 via Android
    4
    数据库加索引就完了,搞那么复杂
    jiangzhuo
    jiangzhuo
    Mar 9, 2017❤️1
    5
    首先大家应该是用 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 亿个网址好像也超过现在的必应了。
    scnace
    scnace
    Mar 9, 2017 via Android
    6
    Bloomfilter 或 数据库加索引
    samcode
    samcode
    Mar 9, 2017❤️1
    7
    先 crc 或者啥 hash 一下
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    8
    @wmttom bloom filter 在这里不好用吧,再不那么重视准确性的情况下,的确可以用
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    9
    检查过了,主要是 url 数据量太大了,写入磁盘的已经几百 GB 了,不过有些 url 是没意义的,需要想办法过滤掉。
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    10
    @gouchaoer 如果没有 redis 这类的,数据库查询会不会慢? 我没测试过,不太了解
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    11
    @samcode 这个可以考虑,谢谢啦。
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    12
    @jiangzhuo 为什么我 72G 的内存刷刷刷就满了 :(,估计有不少费 url ,加上 python 可能比较费内存,你发的这个网址挺好玩的,不知道为什么中间突然降下去了,我一直觉得网页总数是单调增加的,不过从这个网站看,还挺稳定的。
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    13
    @jiangzhuo 哦,对,你的数值错了,是 470 亿,单位是 10 亿,不是 1 亿,所以你的计算要再乘以 10
    binux
    binux
    Mar 9, 2017
    14
    @1a1a11a #9 你已经写磁盘了?没有去重就已经写磁盘了?那么看起来你并没有实时去重的需求啊。那简单,把 url 排个序 sort | uniq 就行了。
    bjlbeyond
    bjlbeyond
    Mar 9, 2017 via iPhone
    15
    对爬取过的 url 计数,超过一定次数后丢弃
    wmttom
    wmttom
    Mar 9, 2017 via iPhone❤️2
    16
    @1a1a11a 很多时候几个 9 的准确性已经足够了。
    或者可以利用 Bloomfilter 的特性,不存在的一定不在,存在的再去查询存储索引,看是不是真的存在。
    Lax
    Lax
    Mar 9, 2017
    17
    用 HLL ,内存占用很少,有些误差
    v2pro
    v2pro
    Mar 9, 2017❤️1
    18
    simhash
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    19
    @binux 我把去重完的 url 写磁盘了和待爬 url 队列写磁盘了,要不内存不一会儿就满,服务器是前兆带宽,我满载了在爬。。。
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    20
    @wmttom 这个主意不错,非常感谢
    allgy
    allgy
    Mar 9, 2017
    21
    #1 楼正解
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    22
    @bjlbeyond 好像不太对题?还是我没理解到点?
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    23
    @Lax HLL 是什么,三个字母不太好搜,能不能给个名字?谢谢啦!
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    24
    @v2pro 好东西,学习了
    jiangzhuo
    jiangzhuo
    Mar 9, 2017
    25
    @1a1a11a 果然大半夜事多了就是精力不集中, 1#说的对 bloomfilter+个 bigtable 什么的足够了
    1a1a11a
    1a1a11a
    OP
    Mar 9, 2017
    26
    @jiangzhuo 谢谢
    Lax
    Lax
    Mar 11, 2017❤️1
    27
    @1a1a11a HyperLogLog , redis 内置支持 https://redis.io/commands/pfadd
    1a1a11a
    1a1a11a
    OP
    Mar 12, 2017
    28
    @Lax 谢谢
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1032 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 18:59 · PVG 02:59 · LAX 10:59 · JFK 13:59
    ♥ Do have faith in what you're doing.