V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SlipStupig
V2EX  ›  Python

爬虫抓取速度自适应问题

  •  
  •   SlipStupig · 2016-05-18 19:17:44 +08:00 · 6408 次点击
    这是一个创建于 3110 天前的主题,其中的信息可能已经有所发展或是发生改变。
    之前都是抓取大型网站,现在抓取一些小型网站,出现把对方给抓死了(并发数 100 多吧),有什么办法能让抓取速度能够自适应,比如:对方是淘宝,开足马力去抓,如果对方是个小网站,能自动测出一个最合适的请求速度去抓取
    第 1 条附言  ·  2016-05-19 00:36:52 +08:00
    我并不是要区分网站域名,而是针对不同机器性能和带宽能实现一个自适应抓取的速度,至于对方有反抓取措施是另外一回事情
    第 2 条附言  ·  2016-05-19 11:55:22 +08:00
    推荐查询 alex ,这样会给我造成额外的流量浪费,而且搞不好,还有可能抓取被封
    47 条回复    2016-05-20 09:04:55 +08:00
    alexapollo
        1
    alexapollo  
       2016-05-18 19:21:44 +08:00   ❤️ 1
    看看 TCP 窗口怎么滑的,非常类似
    anexplore
        2
    anexplore  
       2016-05-18 20:45:23 +08:00
    能够礼貌一些吗?
    VicYu
        3
    VicYu  
       2016-05-18 21:13:19 +08:00
    stcasshern
        4
    stcasshern  
       2016-05-18 21:14:31 +08:00
    想知道对方淘宝,怎么保证开足马力不会被封。。
    binux
        5
    binux  
       2016-05-18 21:54:50 +08:00
    从简单到复杂有非常多种办法,就看你有多少时间和资源去做这个事情了
    em70
        6
    em70  
       2016-05-18 23:04:23 +08:00 via iPhone
    用超级 ping 检测,如果一个域名存在多个 IP 就是大站,只有一个 IP 就是小站
    SlipStupig
        7
    SlipStupig  
    OP
       2016-05-19 00:37:39 +08:00
    @binux 能说说具体方案吗?
    SlipStupig
        8
    SlipStupig  
    OP
       2016-05-19 00:38:13 +08:00
    @anexplore 我哪里有不礼貌的地方,请您指出,我一定改正
    binux
        9
    binux  
       2016-05-19 00:39:22 +08:00
    @SlipStupig 能说说你有多少时间和资源吗?
    SlipStupig
        10
    SlipStupig  
    OP
       2016-05-19 00:42:02 +08:00
    @binux 时间很充足
    tSQghkfhTtQt9mtd
        11
    tSQghkfhTtQt9mtd  
       2016-05-19 00:43:49 +08:00 via Android
    @em70 Anycast 哭晕在厕所
    SlipStupig
        12
    SlipStupig  
    OP
       2016-05-19 00:43:49 +08:00
    @VicYu 这个是限制整体带宽去跑,我要做的是同时抓取 100 个网站,这 100 个网站的并发数都是不一样的
    binux
        13
    binux  
       2016-05-19 00:46:02 +08:00
    @SlipStupig 那你可以统计待抓链接量和上一天的平均响应时间,尝试放大并发,一天之后看平均响应时间是否有变化。没有就继续加大。
    binux
        14
    binux  
       2016-05-19 00:47:44 +08:00
    @binux 响应时间和错误率
    SlipStupig
        15
    SlipStupig  
    OP
       2016-05-19 00:49:04 +08:00
    @binux 这个不太现实,我抓取的网站是不固定的,功能跟百度蜘蛛一样,链接是所有网站放在一个队列里面,至于上一天请求,如果我第一次抓取那个网站如何得到上一天请求?
    binux
        16
    binux  
       2016-05-19 00:53:34 +08:00
    @SlipStupig
    分站点统计都做不到吗?
    你不是说时间很充足吗。。这点数据积累都没有?遇到新网站的概率才多少。。从一个初始值开始做就行了啊。

    所以我问你有多少时间和资源做这件事啊,你看,我给你一个时间很多的方案,你又说不行。
    SlipStupig
        17
    SlipStupig  
    OP
       2016-05-19 01:17:46 +08:00
    @binux 每天都又大量新网站,现在已经抓死了好几个站了,基本上不敢抓了
    menc
        18
    menc  
       2016-05-19 01:30:04 +08:00
    @alexapollo 这位仁兄说的是正解,为什么不借鉴一下呢。
    shiny
        19
    shiny  
       2016-05-19 01:43:04 +08:00
    赞同楼上和一楼
    SlipStupig
        20
    SlipStupig  
    OP
       2016-05-19 02:06:00 +08:00
    @menc 感谢,我也在研究看怎么实现
    @shiny
    binux
        21
    binux  
       2016-05-19 02:39:17 +08:00
    @SlipStupig
    如果是这样
    首先,你的系统必须得支持分站点压力控制吧。
    然后抓之前,先看看对方站点有多少 IP ,查一下站点排名,流量,然后就能定一个差不多的抓取压力了。
    xiamx
        22
    xiamx  
       2016-05-19 06:21:41 +08:00   ❤️ 1
    也可以从 TCP congestion control 算法寻找灵感
    dphdjy
        23
    dphdjy  
       2016-05-19 06:55:09 +08:00 via Android   ❤️ 1
    能把别人抓死,太缺德了!!不看协议吗?
    遇到这种人,我一般直接把数据库扔给他。。。
    lianyue
        24
    lianyue  
       2016-05-19 07:31:44 +08:00 via iPhone
    看 Alexa 排名
    crysislinux
        25
    crysislinux  
       2016-05-19 07:48:23 +08:00
    我一般是有个 client 数组,抓取成功率高就增加 client 的数量,成功率低就减少
    tuutoo
        26
    tuutoo  
       2016-05-19 08:20:17 +08:00
    每个网站设置一个 sleep 值,设定数据超时的值 比如 1 分钟 就给这 sleep 值+30 秒,直到不出现超时情况。
    tuutoo
        27
    tuutoo  
       2016-05-19 08:20:53 +08:00
    遇到超时时就加网站对应 sleep 值。
    tscat
        28
    tscat  
       2016-05-19 08:27:02 +08:00 via iPhone   ❤️ 1
    我觉得楼上有人说你能礼貌点。。。应该是说,对网站礼貌点吧。。
    onion83
        29
    onion83  
       2016-05-19 09:24:13 +08:00   ❤️ 1
    可以模拟一下退火算法,从服务器响应速度动态调整抓取频率,以前我有看过相关文章,可惜可以找不到了....
    anyforever
        30
    anyforever  
       2016-05-19 10:51:50 +08:00
    天天研究抓站的,我都觉得很恶心,跟小偷有什么区别?
    SlipStupig
        31
    SlipStupig  
    OP
       2016-05-19 11:52:28 +08:00
    @anyforever 今天才发现 google 和百度是靠抢劫起家的啊
    SlipStupig
        32
    SlipStupig  
    OP
       2016-05-19 12:04:34 +08:00
    @tuutoo 第一次抓取是未知的,如果对方能承受,速度就明显下降了,如果是这样预设值的方式的话,不如设置级别去减少
    SlipStupig
        33
    SlipStupig  
    OP
       2016-05-19 13:09:49 +08:00
    @onion83
    @xiamx 感谢两位,我好好研究一下
    fivesmallq
        34
    fivesmallq  
       2016-05-19 13:40:12 +08:00
    多个队列随机投放,拿到 url 根据 host 一致性 hash 抓取
    SlipStupig
        35
    SlipStupig  
    OP
       2016-05-19 13:40:47 +08:00
    @fivesmallq 这样能控制速度?
    fivesmallq
        36
    fivesmallq  
       2016-05-19 13:46:43 +08:00
    不好意思,没看清楚, redis 里存放每个 host 对应的等待时间,抓一次,睡眠几秒这样。 然后每次抓取的时候,记录响应时间,到晚上 12 点算一下平均数,第一次直接存放,之后和之前的对比,如果响应时间变长,等待时间就加,否则减,等待时间的变化可能是 1,2,4,8 这样
    SlipStupig
        37
    SlipStupig  
    OP
       2016-05-19 14:12:57 +08:00
    @fivesmallq 抓取一次等几秒那就不会出现一个抓取自适应的问题,我等足够长的时间就行,问题是我每天都要抓取大量新的网站,之前我是完全不知道的,也就是我每次抓取一个新站点基本上都在等,这样会导致抓取特别慢。
    按照你的方法,我还多了一个新挑战,我假设一个非常乐观的情况,当我收录网站在 10 万级别的时候,假设我每个站点的快照内容是 100 个 URL ,那么我得存 1000 万这样的响应值,然后分批计算他们的平均响应值....这个成本有点高啊!
    fivesmallq
        38
    fivesmallq  
       2016-05-19 14:22:57 +08:00
    @SlipStupig 只是一个思路而已,你可以自己扩展,新网站你可以设定一个比较低的初始值,响应值你也可以分阶段计算啊。自己再多想想,完善下。
    fcicq
        39
    fcicq  
       2016-05-19 14:34:22 +08:00   ❤️ 3
    别说并发 100, 对同一个 IP 每秒 10 个请求以上你就是个正规爬虫很多网站站长都不愿意. 楼主如果不能给人家的网站送流量去, 就老实的 10 秒间隔抓一页, 每天 5000 个页面封顶比较好. 先基本解决页面的排名问题再正反馈的加速抓取.
    SlipStupig
        40
    SlipStupig  
    OP
       2016-05-19 15:22:55 +08:00
    @fcicq 觉得可行
    am241
        41
    am241  
       2016-05-19 15:38:32 +08:00 via Android
    延迟上一次的响应时间
    binux
        42
    binux  
       2016-05-19 15:49:22 +08:00 via Android
    连查一下 Alexa 都会流量浪费,存 100 万都成本高。。你资源到底多么少啊。。我怀疑你根本没能力给一个非共享的正经网站抓挂了。
    看来我一开始就问你有多少时间和资源真是问对了。
    SlipStupig
        43
    SlipStupig  
    OP
       2016-05-19 17:45:35 +08:00
    @binux 首先感谢你积极的回复,你这种质疑我本来不想回你的,因为你怀疑我有没能力没任何意义。
    我只是想知道用什么算法或者一些其它比较好的方法会比较好,我认为这种碎片化的方案带来额外的查询和存储,如果所有的功能都是这种零散代码维护起来我不认为会有什么好,所以这种显然不是最优的方案带来的额外付出,在我看来多少都是浪费。
    wweir
        44
    wweir  
       2016-05-19 18:00:27 +08:00   ❤️ 1
    好久没搞爬虫了,不着能从 TCP/http 的角度解决这个问题,绝对是大大的支持。先 mark 一下。

    顺便提下,正常的 http 包头都有时间戳,可以通过解析时间戳冲某种成都上得出网站的相应速度。
    binux
        45
    binux  
       2016-05-19 18:12:03 +08:00
    @SlipStupig 压力控制和挖掘本来就可以独立为一个或者多个模块,你居然称之为「零散代码」,你的系统到底有多小?

    既然你说你的爬虫「功能跟百度蜘蛛一样」,我告诉你的第一个方案就是「百度蜘蛛」所用的。
    当然,根据你爬虫的规模,可以使用简化的方法。但是根据是否需要快启动,你手头永远的数据,是否要防 ban ,你永远的 ip 池大小,以及你要达到的效果;方法实在是太多。你是否真的想清楚了?
    anyforever
        47
    anyforever  
       2016-05-20 09:04:55 +08:00
    @SlipStupig 他们起码会反馈流量回来给你。算的上互惠互利。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1746 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 16:37 · PVG 00:37 · LAX 08:37 · JFK 11:37
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.