网站地图 | RSS订阅 老铁博客 - 上海SEO优化|上海网站建设|蜘蛛池出租|站群代搭建
你的位置:首页 » 网站建设 » 正文

如何让爬虫一天抓取100万张网页

2019-8-7 7:26:45 | 作者:老铁SEO | 0个评论 | 人浏览

  前一两年抓过某工商信息网站,几三周时间大约抓了过千万多万张页面。那时由于公司没啥经费,报销又拖得很久,不想花钱在很多机器和带宽上,所以当时花了较多精力研究如何让一台爬虫机器达到抓取极限。

  爬虫这两年貌似成为了一项必备技能,无论是搞技术的,做产品的,数据分析的,金融的,初创公司做冷启动的,都想去抓点数据回来玩玩。这里面绝大多数一共都只抓几万或几十万条数据,这个数量级其实大可不必写爬虫,使用 chrome 插件 web scraper 或者让 selenium 驱动 chrome 就好了,会为你节省很多分析网页结构或研究如何登陆的时间。

  本篇只关注如何让爬虫的抓取性能最大化上,没有使用scrapy等爬虫框架,就是多线程+Python requests库搞定。

  对一个网站定向抓取几十万张页面一般只用解决访问频率限制问题就好了。对机器内存,硬盘空间,URL去重,网络性能,抓取间隙时间调优一般都不会在意。如果要设计一个单台每天抓取上百万张网页,共有一亿张页面的网站时,访问频率限制问题就不是最棘手的问题了,上述每一项都要很好解决才行。硬盘存储,内存,网络性能等问题我们一项项来拆解。

  所以千万级网页的抓取是需要先设计的,先来做一个计算题。共要抓取一亿张页面,一般一张网页的大小是400KB左右,一亿张网页就是1亿X200KB=36TB。这么大的存储需求,一般的电脑和硬盘都是没法存储的。所以肯定要对网页做压缩后存储,可以用zlib压缩,也可以用压缩率更好的bz2或pylzma 。

  但是这样还不够,我们拿天眼查的网页来举例。天眼查一张公司详情页的大小是700KB 。

  一亿个100KB(9TB)还是太大,要对网页特殊处理一下,可以把网页的头和尾都去掉,只要body部分再压缩。因为一张html页面里head/head和footer/footer大都是公共的头尾信息和js/css代码,对你以后做正文内容抽取不会影响(也可以以后做内容抽取时把头尾信息补回去就好)。

  再来说内存占用问题,做爬虫程序为了防止重复抓取URL,一般要把URL都加载进内存里,放在set()里面。拿天眼查的URL举例:

  这个完整URL有44个字节,一亿个URL就是4G,一亿个URL就要占用4G内存,这还没有算存这一亿个URL需要的数据结构内存,还有待抓取URL,已抓取URL还保存在内存中的html等等消耗的内存。

  但是如果你是用的野云主机,用来不断拨号用的非正规云主机,这700多M内存也是吃不消的,机器会非常卡。

  就还需要想办法压缩URL的内存占用,可以使用BloomFilter算法,是一个很经典的算法,非常适用海量数据的排重过滤,占用极少的内存,查询效率也非常的高。它的原理是把一个字符串映射到一个bit上,刚才23402373占8个字节,现在只占用1个bit(1字节=8bit),内存节省了近64倍,以前700M内存,现在只需要10多M了。

  不过奇怪,bloom里没有公有方法来判断URL是否重复,我用的__contains__()方法,也可能是我没用对,不过判重效果是一样的。

  单台机器,单个IP大家都明白,短时间内访问一个网站几十次后肯定会被屏蔽的。每个网站对IP的解封策略也不一样,有的1小时候后又能重新访问,有的要一天,有的要几个月去了。突破抓取频率限制有两种方式,一种是研究网站的反爬策略。有的网站不对列表页做频率控制,只对详情页控制。有的针对特定UA,referer,或者微信的H5页面的频率控制要弱很多。

  另一种方式就是多IP抓取,多IP抓取又分IP代理池和adsl拨号两种,我这里说adsl拨号的方式,IP代理池相对于adsl来说,我觉得收费太贵了。要稳定大规模抓取肯定是要用付费的,一个月也就100多块钱。

  adsl的特点是可以短时间内重新拨号切换IP,IP被禁止了重新拨号一下就可以了。这样你就可以开足马力疯狂抓取了,但是一天只有24小时合86400秒,要如何一天抓过百万网页,让网络性能最大化也是需要下一些功夫的,后面我再详说。

  至于有哪些可以adsl拨号的野云主机,你在百度搜vps adsl,能选择的厂商很多的。大多宣称有百万级IP资源可拨号,我曾测试过一段时间,把每次拨号的IP记录下来,有真实二三十万IP的就算不错了。

  选adsl的一个注意事项是,有的厂商拨号IP只能播出C段和D段IP,110(A段).132(B段).3(C段).2(D段),A和B段都不会变,靠C,D段IP高频次抓取对方网站,有可能对方网站把整个C/D段IP都封掉。

  C/D段加一起255X255就是6万多个IP全都报废,所以要选拨号IP范围较宽的厂商。 你要问我哪家好,我也不知道,这些都是野云主机,质量和稳定性本就没那么好。只有多试一试,试的成本也不大,买一台玩玩一个月也就一百多元,还可以按天买。

  因为比adsl拨号贵很多,因为全速抓取时,一个反爬做得可以的网站10秒内就会封掉这个IP,所以10秒就要换一个IP,理想状况下一天86400秒,要换8640个IP。

  上面步骤做完了,每天能达到抓取五万网页的样子,要达到百万级规模,还需把网络性能和抓取技术细节调优。

  每个网站对短时间内访问次数的屏蔽策略不一样,这需要实际测试,找出抓取效率最大化的时间点。先开一个线程,一直抓取到IP被屏蔽,记录下抓取耗时,总抓取次数,和成功抓取次数。 再开2个线程,重复上面步骤,记录抓取耗时,总的和成功的抓取次数。再开4个线程,重复上面步骤。整理成一个表格如下,下图是我抓天眼查时,统计抓取极限和细节调优的表格:

  从上图比较可以看出,当有6个线程时,是比较好的情况。耗时6秒,成功抓取80-110次。虽然8个线秒,但是成功抓取次数已经在下降了。所以线个。

  从上面的图片看到,貌似每隔6秒拨号是一个不错的选择。可以这样做,但是我选了另一个度量单位,就是每总抓取120次就重新拨号。为什么这样选呢?从上图也能看到,基本抓到120次左右就会被屏蔽,每隔6秒拨号其实误差比较大,因为网络延迟等各种问题,导致6秒内可能抓100次,也可能抓120次。

  要优化requests.get(timeout=1.5)的超时时间,不设置超时的话,有可能get()请求会一直挂起等待。而且野云主机本身性能就不稳定,长时间不回请求很正常。如果要追求抓取效率,超时时间设置短一点,设置10秒超时完全没有意义。对于超时请求失败的,大不了以后再二次请求,也比设置10秒的抓取效率高很多。

  上面步骤已算把单台机器的抓取技术问题优化到一个高度了,还剩一个优化野云主机的问题。就是每次断开拨号后,要等待几秒钟再拨号,太短时间内再拨号有可能又拨到上一个IP,还有可能拨号失败,所以要等待6秒钟(测试值)。所以要把拨号代码改一下:

  而且 os.popen(rasdial 网络名称 adsl账号名 adsl密码) 拨号完成后,你还不能马上使用,那时外网还是不可用的,你需要检测一下外网是否联通。

  code为0时表示联通,不为0时还要重新拨号。而ping也很耗时间的,一个ping命令会ping 4次,就要耗时4秒。

  上面拨号等待6秒加上 ping 的4秒,消耗了10秒钟。上面猿人学Python说了,抓120次才用6秒,每拨号一次要消耗10秒,而且是每抓120次就要重拨号,想下这个时间太可惜了,每天8万多秒有一半时间都消耗在拨号上面了,但是也没办法。

  当然好点的野云主机,除了上面说的IP范围的差异,就是拨号质量差异。好的拨号等待时间更短一点,拨号出错的概率要小一点。

  通过上面我们可以轻松计算出一组抓取的耗时是6秒,拨号耗时10秒,总耗时16秒。一天86400秒,就是5400组抓取,上面说了一组抓取是120次。一天就可以抓取5400X120=64万张网页。

  按照上述的设计就可以做到一天抓60多万张页面,如果你把adsl拨号耗时再优化一点,每次再节约2-3秒,就趋近于百万抓取量级了。

  另外野云主机一个月才100多,很便宜,所以你可以再开一台adsl拨号主机,用两台一起抓取,一天就能抓一百多万张网页。几天时间就能镜像一个过千万网页的网站。

  没必要,这里的整个抓取关键是网络性能,而不是程序性能。用异步把程序性能提高了,单位时间的抓取次数是提高了,但是这样反而会击中对方网站的访问频率控制策略。

  一个中小型网站的带宽在5M以内,大一点的网站带宽可能10-30M,超大型的另算。

  一张网页300KB,对方一般会压缩后传输给浏览器,就按压缩后30KB算,你的爬虫一秒请求20次,带宽就是600KB。可能一个网站每天都有几十个爬虫都在爬,我们按有10个爬虫在同时抓取,就是这些爬虫一秒内就要消耗600KBX10=6M带宽。

  再加上还有正规爬虫,人家网站上的正常用户访问这些,算下来可能一共要消耗10M带宽。一般的大中型网站都是吃不消的。

  前一两年抓过某工商信息网站,几三周时间大约抓了过千万多万张页面。那时由于公司没啥经费,报销又拖得很久,不想花钱在很多机器和带宽上,所以当时花了较多精力研究如何让一台爬虫机器达到抓取极限。 Python爬虫这两年貌似成为了一项必备技能,无论是搞技术的,做产品的,数据分析的,金...

  前一两年抓过某工商信息网站,几三周时间大约抓了过千万多万张页面。那时由于公司没啥经费,报销又拖得很久,不想花钱在很多机器和带宽上,所以当时花了较多精力研究如何让一台爬虫机器达到抓取极限。 Python爬虫这两年貌似成为了一项必备技能,无论是搞技术的,做产品的,数据分析的,金...

  简要[1] 优化存储硬盘[2] 优化内存,URL去重[3] 网络性能,抓取技术细节调优[4] 反抓取访问频率限制[5] 总结[6] 问题答解[7] 原文 本篇只关注如何让爬虫的抓取性能最大化上,没有使用scrapy等爬虫框架,就是多线程+Python requests库搞定...

  我的一位朋友,因为孩子的事情,弄得焦头烂额,知道我是做心理咨询的,就一直想找我咨询。 孩子初中学习很好,以优异成绩考到高中后,不知道什么原因,下滑很厉害,到后来成了班级倒数。无奈,给孩子转了学,又不知道因为什么问题搞得不好,只得退学。这时朋友就有了很强的着急感。...

  引子 尹沧刹不是她的本名,是她自己取的。至于她为什么不用本名,没人知道,为什么取这样奇怪的名字,也没人知道。其实她自己也不知道。她取这个名字的时候,所做的仅仅是输了拼音,在输入法给的页面上挑了几个字。 这实在是个不好读的名字,但尹沧刹也不准备让自己或别人一天念叨这名字,总之...

  收敛自己的脾气,经常要保持沉默,因为冲动会做下让自己无法挽回的事情。 你没那么多观众,别那么累。 做一个简单的人,踏实而务实。不沉溺幻想,更不庸人自扰。 温和对人对事。 不随意发脾气,谁都不欠你的,这个世界没有"应该"二字。保持头脑清醒,明白自己渺小,切忌自我陶醉。炮打出头...

  前言: 最近的迭代需求需要实现个仪表盘,正好时间比较多,索性就从头看一遍Quartz 2D,就有了今天这篇笔记,闲话不多说,直接开始,由于内容过多,此篇主要对Quatrz 2D做个大致的介绍和怎么用Quartz 2D绘制简单图形、曲线、文字和图片,后续大概会有3到5篇对Co...

  一家三口吃了顿快餐,爸爸带着儿子去上围棋课了,我一个人坐在这里发个小呆,消化一下! 窗外已黑,霓虹灯已亮,夜色渐渐猖狂,这样的我应该是幸福的吧!我经常告诉自己,自己没有嫁错人,是幸福的,他不仅包容我的坏脾气,也十分顾家,家里的开支几乎不过问,我花钱也基本自己决定...

  • 本文来自: 老铁博客,转载请保留出处!欢迎发表您的评论
  • 相关标签:爬虫抓取  
  • 已有0位网友发表了一针见血的评论,你还等什么?

    必填

    选填

    记住我,下次回复时不用重新输入个人信息

    必填,不填不让过哦,嘻嘻。

    ◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

    海南开文旅资源对接大会 达成意向投资额超40亿元
    英国资产料将升值 英国大选出口民调显示保守党狂胜
    英国大选约翰逊赢定了?欧盟对民调结果表示欢迎
    12月13日现货黄金、白银、原油、外汇短线交易策略
    北京市社会福利中心原党委副书记贠根华被双开
    上市折戟后WeLab融资11亿元 股东个个来头不小
    手机店店员监守自盗:利用漏洞5天盗销十余部手机
    美财政部发售中国鼠年“吉利钱” 已销售200万套
    美国财政部发售中国鼠年"吉利钱" 已累计销售200万套
    有新的假期要来,网友却在流泪