先做个小示例,不用废话谈理论,没有实践的空谈都是扯蛋误导人。
这篇文章不讨论线程 协程的理论。只讨论标题的主题问题,爬虫速度。
# coding=utf-8 import requests,time count=0 urlx= 'http://www.xxsy.net/' # 'http://www.danmeila.com/' http://www.sina.com.cn/ 'http://www.qingkan9.com/' # # 'http://www.qingkan9.com/' def fun(url): try: print url resp=requests.get(url) if resp.status_code!=200: print '***',resp.status_code global count count+=1 print count,' ',round((time.time()-start_time),3) except Exception as e: pass def single_fun(): for i in range(1000000): fun(urlx) def gevent_fun(): from gevent import monkey monkey.patch_all(socket=True,select=True) from gevent.pool import Pool gevent_pool = Pool(800) urls = [urlx for i in range(1000000)] gevent_pool.map(fun, urls) def thread_fun(): import threadpool thread_pool = threadpool.ThreadPool(200) requestsx = threadpool.makeRequests(fun, [urlx for i in range(1000000)]) [thread_pool.putRequest(req) for req in requestsx] thread_pool.wait() def funx(a,b=None): print a,b if __name__=="__main__": start_time=time.time() #single_fun() ##用什么就把其他的注释掉,三种模式 #gevent_fun() thread_fun()
此图为顺序执行。
此图为协程,800并发。
此图为200线程。
上面的是以请求潇湘书院首页为例。
可以看到单个请求的同步执行,在120秒内的请求数量远少于后两者,不管运行多少次,都是这样的明显少于后两者。
协程和线程相比,120秒内请求的数量非常接近,受网速的小幅波动影响可能每次运行结果都会差点(运行程序时候把其他所有连接网络的软件关闭掉,减小干扰),但不管如何,两者都是非常接近的。
协程可以开启更多,但线程开大概500以上后就会出错,包括web性能测试工具jmter loadrunner这些工具也都是单机并发有限的,并发设置多了一样会报错。我这里开多线程用200,协程用800,尽管协程能开更多,但网速早就跑满了。
线程和协程都能使网速一直跑满。在网速一直持续饱满的情况下,那么一定时间内,能够请求的字节总数都是一样的,所以这和多线程和协程在120秒内的请求个数非常接近,基本是一致的。
潇湘书院根本不需要开800协程,100协程早就能足够跑满网速了。
还有人说开协程可以开100万,线程开不了那么多,所以协程有优势,这完全是扯鸡巴蛋,我可以直接判断他从没有开过100万协程 requets,不服的可以把800改成1000000看看效果,我也基本可以95%断定他连1万协程requests都没有试过。没人遇到cant watch more than 1024 sockets了吗。只要不是响应时间差的离谱的网站,100协程早就足够了。再加更多也不能让120秒内请求更多的页面。
速度乘以时间等于路程。
网络使用速度*时间=总字节数。
两个变量相同的情况下得到的乘积肯定是一样的。这种常识不需要再理论了。
说协程比线程爬取速度更快那么就是扯蛋了,不要看了一点理论,就自以为掌握了精髓,对事情妄下结论。
至于在一次面试中,一个创业小公司的面试官说他看网上是python多线程是假的,他爬虫只用多进程从不用线程,这跟是无语了,为什么只是看别人说,自己不去试下。不知道那面试官是看了网上正确的东西的但他看一半理解的断章取义了,还是他看了网上错误的东西。全指望多进程是不好的,多进程占用内存巨大,启动多进程需要的时间特别漫长,多进程能不能使网速使用率更高,满速了就不能再突破。
上面的实验使用潇湘书院做的,测试过程中还是用了一个很小的网站,但那个网站是很小的,响应速度超级慢,不管开了多少线程 协程都只能达到100多kb,可能人家的服务器下行带宽就那样。
测试过程中还是用了新浪网首页,请求新浪网的情况下,新浪网作为首屈一指的大网站,响应速度是非常非常好,同时一个页面的字节数非常大,所以使用单个请求同步执行和协程 线程相比,虽然差了一点,但是远没有潇湘书院那么夸张差了10倍。也就是响应时间越大的网站,gevent threding比单线程优势才能更明显。
搞东西,不要光理论就想当然的认为怎么样了,即使是喜欢看理论的人,也需要实践。三国时期的蜀国马谡是怎么死的,战国时期的赵国马服子是怎么死的,熟读兵书说起理论一套一套的,仅从一些理论就过于的认为一件事怎么样,太想当然了。 马谡 和马服子既可怜又可恨,可怜是他们都不算大坏人,但结局都是死的非常惨,可恨是他们只喜欢纸上谈兵说起东西来一套一套的的,不注重实践,最终不仅是害了自己,还连累三军,马谡和马服子直接加速了蜀国和赵国的灭国之灾。 如果当时不派这两个人去带兵打仗,随便派个垃圾小兵做主将都不会出现输得这么惨。