怎样设计一个分布式的爬虫服务? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
wangleineo

怎样设计一个分布式的爬虫服务?

  •  
  •   wangleineo Feb 22, 2016 6822 views
    This topic created in 3720 days ago, the information mentioned may be changed or developed.

    爬虫程序有一个很大的问题,就是服务端会限制一个 IP 的请求频率,甚至封禁一个 IP 。解决这个问题的一个办法就是用多个不同网络的主机或代理来发出请求(同时限制频率),最后再把爬取的结果汇总。

    Scrapy Cloud 就是一个这样的分布式服务: https://www.scrapinghub.com/, 是 scrapy 的作者们写的一个商业化的 SaaS 服务,核心非开源。

    问题是:在接收到一个爬虫请求以后,怎样分配爬取链接到各个 worker 上面?这个问题似乎比较复杂,因为需要爬取的链接不是一个线性的列表,而是一个图结构(图中每个节点是一个需要爬取的链接),在预先只有图的根节点的情况下,怎样把爬取任务分配给各个 Worker 节点,又使得各个节点的任务尽量平均又不重合呢?

    比如一个策略是,从根节点展开第一个层次的所有链接,然后把这些链接平均分配到各个 worker 开始爬取,但是有可能第二层有很多个公共的链接,各个 worker 就会重复很多爬取动作。

    有什么好的想法吗?

    16 replies    2016-09-09 09:37:11 +08:00
    gouwudang
        1
    gouwudang  
       Feb 22, 2016
    楼主对这方面感兴趣欢迎来我司,我们在找 Python 工程师加盟,更好的解决这方面的问题
    yangqi
        2
    yangqi  
       Feb 22, 2016
    中间加一层 scraper ,专门爬链接,然后再分配给 worker 抓取页面
    knightdf
        3
    knightdf  
       Feb 22, 2016
    我是写了一个基于 redis 的 bloomfilter 来做, master 节点只分配入口 url ,集群子节点只管抓取,管理全部 master 节点来管理,对 子节点定时关机换机器。跑在 AWS 上
    yixiang
        4
    yixiang  
       Feb 22, 2016   1
    无经验。随意想到的思路:
    多个 worker ,一个 center , center 负责分配任务,爬虫爬完后把结果返回给 center ,只在 center 这里存储整个图和工作怎样分配。

    其实类似于……
    一个爬虫+一堆匿名代理,请求一个就换一个代理。

    估计实际环境中会遇到许多问题。
    wangleineo
        5
    wangleineo  
    OP
       Feb 22, 2016
    @gouwudang IT 桔子上没看到你们融资啊,是已经闷声发大财了吗?

    @yangqi 这样的话, scraper 需要访问所有链接了,还是很容易被禁。 worker 只是分担了抓取动作本身。
    wangleineo
        6
    wangleineo  
    OP
       Feb 22, 2016
    @knightdf 那 bloomfilter 是做什么的?看一个 url 有没有被爬过?
    Kirscheis
        7
    Kirscheis  
       Feb 22, 2016
    这样是否可行?
    worker 首先 parse ,之后把抽取的 url 返回给 master ,然后从 master 的 waiting list 领取下一个 request 。
    master 维护一个保存着爬过的 url 的库, worker 返回的所有链接用 bloomfilter 快速检查是否爬过,然后把没爬过的加入 waiting list 。
    sohoer
        8
    strong>sohoer  
       Feb 22, 2016
    一个 Crawler 负责任务调度,将需要采集网址通过负载均衡的方式分发给其它 Crawler
    knightdf
        9
    knightdf  
       Feb 22, 2016
    @wangleineo 你不是要解决 URL 分配的问题么,这样我的子节点就只用接受根节点这一个 URL 任务了
    izoabr
        10
    izoabr  
       Feb 22, 2016
    要分是不是得 hadoop 了?
    chinajik
        11
    chinajik  
       Feb 22, 2016
    客户机方面:
    ip ban 的话就用 ADSL 服务器.
    Captcha 用 selenium 截图用第三方平台解析

    消费端:
    走队列建索引, 基本数据传输走 websocket 请求 keepalive 穿透性强



    再写些拨号脚本,重启脚本的,自动阀值调控, 多线程就不用讲了。

    爬虫对实时性要求高的,基本看被爬的服务器的阀值峰值,基本上核心价值观就是你不影响他线上业务,一定程度的爬虫运维是睁一只眼闭一只眼的...
    wangleineo
        12
    wangleineo  
    OP
       Feb 22, 2016
    @Kirscheis
    @knightdf
    scrapinghub 就是这么做的: https://github.com/scrapinghub/frontera
    这个组件的功能就是根据一些策略给 worker 分配爬取任务, worker 爬到新的 url 再提交给 frontera.
    knightdf
        13
    knightdf  
       Feb 22, 2016
    @wangleineo 对的,这样设计集群靠谱点, slave 只做抓取的任务
    yangqi
        14
    yangqi  
       Feb 22, 2016
    @wangleineo scraper 也可以是分布式的啊
    SlipStupig
        15
    SlipStupig  
       Feb 23, 2016
    你如果是遇到被 ban 掉,你解决方案肯定不是去搞分布式,几种方案
    1.伪造 x-forward-for 头部去欺骗,不一定能成功
    2.去用 http 代理,一些网站会拉黑一些代理
    3.用 tor 节点
    4.adsl 重新拨号,这个不靠谱, adsl 的 ip 量有限,而且不一定恰好遇到 ip 释放

    结论就是,花点钱去买代理吧
    ssllff123
        16
    ssllff123  
       Sep 9, 2016
    @knightdf scrapy 实现了这个功能。 scrapy-redis 但是我正在学习中
    About     Help     Advertise     Blog     API     FAQ     Solana     2690 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 46ms UTC 14:34 PVG 22:34 LAX 07:34 JFK 10:34
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86