zoukankan      html  css  js  c++  java
  • 高效爬虫实战经典案例

    最近,我接到一个任务,具体来说就是:

    使用百度来搜索30万关键词,把搜索结果中出现的网站链接全部储存下来。

    我们来计算一下,30万关键词,每个关键词百度会给出75个页面,就是2250万个网页的爬虫量。考虑到延时等在内,每秒平均处理一个页面,就需要22500000/(24*3600) = 260天时间,我们用并行处理,十个进程,并行,也需要26天,这简直不可接受

    我的改进之路:

    首先,考虑多线程,python的多线程不是那么强势,我最开始是这么做的:每一个关键词的75个url的处理,把处理出来的数据放在mysql里面,使用多线程,当处理完后,再来处理下一个关键词,这个程序我的实际运行效率是一个单词大概30秒,也就是一天能处理三千多个单词,程序要运行一百天

    然后,我觉得爬每个关键词的结果放在mysql里面,因为要避免放入重复的数据,所以我每次都要判断是否存在,这个步骤很费时间,我想到了redis,并做了实验,由于redis在内存中,而且是键值对的形式,我把爬到的网址当作键,就不用检查是否重复了,并且我计算了一下,假设我最终得到500万不同的网址,每个网址的存储花费30Byte,也才5000000*30/1024 = 146484KB = 143MB,内存完全能够放下,至此,存储方面就可以不用怎么优化了

    接着,我们发现一个问题,把每个关键词的75个url作为一个多线程模块,运行完之后,才处理下一个关键词,那么必然有一部分时间的并行量不够,这浪费了,所以我想把所有的单词的url都放入多线程,设置最大并行线程数,但是这样的问题就是不知道某个单词是否已经处理完毕,所以我进行预处理,专门使用一个程序来产生所有的url,并存入txt里面,这一步我也计算过,容量没问题,之后把整个url_list进行多线程操作,就快多了

    还有,我发现百度的搜索页面可以一次显示50条信息,而不是最初的十条,这样,我的页面数量瞬间减少到了五分之一,又是一大进步。

    同时,我研究了爬取的速度绝对是受网速影响很大的,比如,1MB/S,那么每秒最多处理1MB的数据,所以这个时候,使用Gzip对网页进行压缩,就能大大增加每秒可以下载的网页数目,增加了爬虫效率。

    最终结果:

    我使用预处理,得到了四百八十多万url,然后,20分钟,处理了28000条,我们算一下,每分钟处理一千四百个url,那么,我们所需时间为:4800000/(24*60*1400) = 2.3天,而且还没有用到多进程,比起最开始的十个进程并行,还需要26天,时间减少到了百分之一不到,真的很爽

  • 相关阅读:
    如何利用 JConsole观察分析Java程序的运行,进行排错调优
    【解决】网站运行一段时间后就无法访问,重启Tomcat才能恢复
    不允许一个用户使用一个以上用户名与一个服务器或共享
    SVN升级到1.8后 Upgrade working copy
    Windows Server 2012 R2 创建AD域
    JTA 深度历险
    svn merge error must be ancestrally related to,trunk merge branch报错
    OutputStream-InputStream-FileOutputStream-FileInputStream-BufferedOutputStream-BufferedInputStream-四种复制方式-单层文件夹复制
    SVN提交时响应很慢,我是这样解决的。
    docker学习6-docker-compose容器集群编排
  • 原文地址:https://www.cnblogs.com/gongbo/p/6520624.html
Copyright © 2011-2022 走看看